<?php

declare(strict_types=1);

namespace App\Controllers\Api;

/**
 * Saved delivery addresses for logged-in customers.
 * All endpoints require a valid bearer token.
 */
class AddressController extends BaseApiController
{
    // GET /api/v1/addresses
    public function index(): void
    {
        $cid = $this->requireCustomer();
        $rows = $this->db->fetchAll(
            "SELECT id, label, address_line, city, latitude, longitude, is_default
               FROM customer_addresses
              WHERE customer_id = ?
              ORDER BY is_default DESC, id DESC",
            [$cid]
        );
        $this->ok($rows);
    }

    // POST /api/v1/addresses
    public function store(): void
    {
        $cid = $this->requireCustomer();

        $label   = trim((string)$this->post('label', 'Home'));
        $line    = trim((string)$this->post('address_line'));
        $city    = trim((string)$this->post('city'));
        $lat     = $this->post('latitude')  !== '' ? (float)$this->post('latitude')  : null;
        $lng     = $this->post('longitude') !== '' ? (float)$this->post('longitude') : null;
        $default = (int)($this->post('is_default', 0)) ? 1 : 0;

        if ($line === '') $this->fail('Address is required.');
        if ($label === '') $label = 'Home';

        // First address for a customer becomes the default automatically.
        $count = (int)$this->db->fetchValue(
            "SELECT COUNT(*) FROM customer_addresses WHERE customer_id = ?", [$cid]
        );
        if ($count === 0) $default = 1;

        if ($default === 1) {
            $this->db->update('customer_addresses',
                ['is_default' => 0], ['customer_id' => $cid]);
        }

        $id = $this->db->insert('customer_addresses', [
            'customer_id'  => $cid,
            'label'        => $label,
            'address_line' => $line,
            'city'         => $city,
            'latitude'     => $lat,
            'longitude'    => $lng,
            'is_default'   => $default,
        ]);

        $row = $this->db->fetchOne(
            "SELECT id, label, address_line, city, latitude, longitude, is_default
               FROM customer_addresses WHERE id = ?", [$id]
        );
        $this->ok($row, 'Address saved.');
    }

    // POST /api/v1/addresses/{id}/location
    public function updateLocation(array $params = []): void
    {
        $cid  = $this->requireCustomer();
        $addr = $this->owned((int)($params['id'] ?? 0), $cid);
        $lat  = $this->post('latitude')  !== '' ? (float)$this->post('latitude')  : null;
        $lng  = $this->post('longitude') !== '' ? (float)$this->post('longitude') : null;
        if ($lat === null || $lng === null) $this->fail('Location is required.');

        $data = ['latitude' => $lat, 'longitude' => $lng];
        // Optionally refresh the address text when provided.
        $line = trim((string)$this->post('address_line'));
        if ($line !== '') $data['address_line'] = $line;

        $this->db->update('customer_addresses', $data, ['id' => $addr['id']]);
        $row = $this->db->fetchOne(
            "SELECT id, label, address_line, city, latitude, longitude, is_default
               FROM customer_addresses WHERE id = ?", [$addr['id']]);
        $this->ok($row, 'Location saved.');
    }

    // POST /api/v1/addresses/{id}/default
    public function setDefault(array $params = []): void
    {
        $cid = $this->requireCustomer();
        $addr = $this->owned((int)($params['id'] ?? 0), $cid);
        $this->db->update('customer_addresses', ['is_default' => 0], ['customer_id' => $cid]);
        $this->db->update('customer_addresses', ['is_default' => 1], ['id' => $addr['id']]);
        $this->ok(null, 'Default address updated.');
    }

    // POST /api/v1/addresses/{id}/delete
    public function delete(array $params = []): void
    {
        $cid  = $this->requireCustomer();
        $addr = $this->owned((int)($params['id'] ?? 0), $cid);
        $wasDefault = (int)$addr['is_default'] === 1;
        $this->db->delete('customer_addresses', ['id' => $addr['id']]);

        // Promote another address to default if we removed the default one.
        if ($wasDefault) {
            $next = $this->db->fetchOne(
                "SELECT id FROM customer_addresses WHERE customer_id = ? ORDER BY id DESC LIMIT 1",
                [$cid]
            );
            if ($next) {
                $this->db->update('customer_addresses',
                    ['is_default' => 1], ['id' => $next['id']]);
            }
        }
        $this->ok(null, 'Address removed.');
    }

    // ── Helpers ─────────────────────────────────────────────────────────────────

    private function requireCustomer(): int
    {
        $user = $this->requireAuth();
        $cid  = $this->customerId($user);
        if ($cid === 0) $this->fail('Customer profile not found.', 404);
        return $cid;
    }

    private function owned(int $id, int $cid): array
    {
        $row = $this->db->fetchOne(
            "SELECT * FROM customer_addresses WHERE id = ? AND customer_id = ?",
            [$id, $cid]
        );
        if (!$row) $this->fail('Address not found.', 404);
        return $row;
    }
}
