<?php

declare(strict_types=1);

namespace App\Controllers;

use App\Models\CustomerModel;
use Core\Request;
use Core\Auth;

final class CustomerController extends BaseController
{
    private CustomerModel $model;

    public function __construct()
    {
        parent::__construct();
        Auth::requireLogin();
        $this->model = new CustomerModel();
    }

    // ── List ──────────────────────────────────────────────────────────────────

    public function index(): void
    {
        $this->requirePermission('customer.view');
        $page    = max(1, (int) Request::get('page', '1'));
        $search  = trim(Request::get('search', ''));
        $filter  = Request::get('filter', 'all');
        $sort    = Request::get('sort', 'spent');
        $perPage = 20;

        $result = $this->model->list($page, $perPage, $search, $filter, $sort);

        $this->view('customers.index', [
            'title'      => 'Customers',
            'rows'       => $result['rows'],
            'pagination' => paginate($result['total'], $page, $perPage, url('customers')),
            'search'     => $search,
            'filter'     => $filter,
            'sort'       => $sort,
            'total'      => $result['total'],
        ]);
    }

    // ── Detail ────────────────────────────────────────────────────────────────

    public function show(array $params): void
    {
        $this->requirePermission('customer.view');
        $customer = $this->model->find((int) $params['id']);
        if (!$customer) { $this->abort(404); }

        $this->view('customers.show', [
            'title'     => 'Customer: ' . $customer['name'],
            'customer'  => $customer,
            'addresses' => $this->model->addresses((int) $params['id']),
            'orders'    => $this->model->recentOrders((int) $params['id']),
        ]);
    }

    // ── Edit ──────────────────────────────────────────────────────────────────

    public function edit(array $params): void
    {
        $this->requirePermission('customer.edit');
        $customer = $this->model->find((int) $params['id']);
        if (!$customer) { $this->abort(404); }

        $this->view('customers.edit', [
            'title'    => 'Edit Customer',
            'customer' => $customer,
        ]);
    }

    public function update(array $params): void
    {
        $this->requirePermission('customer.edit');
        Request::verifyCsrf();
        $id = (int) $params['id'];

        $name  = trim(Request::str('name'));
        $email = trim(Request::str('email'));
        $phone = trim(Request::str('phone'));
        $note  = trim(Request::str('admin_note'));

        if (!$name || !$email) {
            $this->flash('error', 'Name and email are required.');
            $this->redirect('/customers/' . $id . '/edit');
        }

        $this->model->update($id, [
            'name'      => $name,
            'email'     => $email,
            'phone'     => $phone,
            'is_active' => Request::str('is_active') === '1' ? 1 : 0,
        ], $note);

        $this->flash('success', 'Customer updated.');
        $this->redirect('/customers/' . $id);
    }

    // ── Toggle active ─────────────────────────────────────────────────────────

    public function toggle(array $params): void
    {
        $this->requirePermission('customer.edit');
        Request::verifyCsrf();
        $result = $this->model->toggle((int) $params['id']);
        $this->flash('success', 'Customer ' . $result . '.');
        $this->redirect('/customers');
    }

    // ── Blacklist ─────────────────────────────────────────────────────────────

    public function blacklist(array $params): void
    {
        $this->requirePermission('customer.edit');
        Request::verifyCsrf();
        $id     = (int) $params['id'];
        $reason = trim(Request::str('reason'));

        if (!$reason) {
            $this->flash('error', 'Blacklist reason is required.');
            $this->redirect('/customers/' . $id);
        }

        $adminId = (int) Auth::user()['id'];
        $this->model->blacklist($id, $reason, $adminId);
        $this->flash('success', 'Customer has been blacklisted.');
        $this->redirect('/customers/' . $id);
    }

    public function unblacklist(array $params): void
    {
        $this->requirePermission('customer.edit');
        Request::verifyCsrf();
        $this->model->unblacklist((int) $params['id']);
        $this->flash('success', 'Customer has been removed from blacklist.');
        $this->redirect('/customers/' . $params['id']);
    }

    // ── Delete ────────────────────────────────────────────────────────────────

    public function delete(array $params): void
    {
        $this->requirePermission('customer.delete');
        Request::verifyCsrf();
        $id = (int) $params['id'];

        if (!$this->model->delete($id)) {
            $this->flash('error', 'Cannot delete — customer has existing orders.');
            $this->redirect('/customers/' . $id);
        }

        $this->flash('success', 'Customer deleted.');
        $this->redirect('/customers');
    }

    // ── Export CSV ────────────────────────────────────────────────────────────

    public function export(): void
    {
        $this->requirePermission('customer.delete');
        $rows = $this->model->exportAll();

        header('Content-Type: text/csv');
        header('Content-Disposition: attachment; filename="customers_' . date('Ymd') . '.csv"');
        header('Cache-Control: no-cache');

        $out = fopen('php://output', 'w');
        fputcsv($out, ['Name', 'Email', 'Phone', 'Active', 'Blacklisted', 'Joined', 'Total Orders', 'Total Spent']);

        foreach ($rows as $r) {
            fputcsv($out, [
                $r['name'], $r['email'], $r['phone'],
                $r['is_active'] ? 'Yes' : 'No',
                $r['blacklisted'] ? 'Yes' : 'No',
                date('Y-m-d', strtotime($r['created_at'])),
                $r['total_orders'],
                number_format((float)$r['total_spent'], 2),
            ]);
        }
        fclose($out);
        exit;
    }

    // ── Helper ────────────────────────────────────────────────────────────────

    private function abort(int $code): never
    {
        http_response_code($code);
        $this->flash('error', 'Customer not found.');
        $this->redirect('/customers');
    }
}
