<?php
declare(strict_types=1);

namespace App\Controllers;

use App\Repositories\Container;
use App\Services\Email;

/**
 * Public (no auth) controller for customer to approve or reject a proposed reschedule.
 * Links arrive via email: /reschedule/{token}/approve  or  /reschedule/{token}/reject
 */
class RescheduleController
{
    public function approve(array $params): void
    {
        $appt = $this->findByToken($params['token'] ?? '');
        if (!$appt) { $this->renderInvalid(); return; }

        $newStart = $appt['proposed_start_at'];
        $newEnd   = $appt['proposed_end_at'];

        // Conflict check before confirming
        $artistId = $appt['artist_id'] ?? '';
        if ($artistId) {
            $conflict = \App\Services\Availability::findConflict($artistId, $newStart, $newEnd, $appt['id']);
            if ($conflict) {
                $this->renderConflict($appt);
                return;
            }
        }

        // Apply the new time and auto-approve
        $appt = Container::appointments()->save(array_merge($appt, [
            'start_at'          => $newStart,
            'end_at'            => $newEnd,
            'status'            => 'APPROVED',
            'approved_at'       => now_iso(),
            'proposed_start_at' => null,
            'proposed_end_at'   => null,
            'reschedule_token'  => null,
            'reschedule_reason' => null,
        ]));
        Container::audit()->log('CUSTOMER', 'APPROVE_RESCHEDULE', 'appointment', $appt['id']);

        // Notify staff
        $customer = !empty($appt['customer_id']) ? Container::users()->find($appt['customer_id']) : null;
        $notify = config('mail.notify_email');
        if ($notify && $customer) {
            $name = trim(($customer['first_name'] ?? '') . ' ' . ($customer['last_name'] ?? ''));
            $when = (new \DateTimeImmutable($newStart))->format('l, F j · g:i A');
            Email::send($notify,
                "✅ Reschedule approved by {$name}",
                Email::template('Reschedule approved',
                    "<p><strong>{$name}</strong> has accepted the new time: <strong>{$when}</strong>.</p><p>The appointment is now <strong style='color:#d4af37'>APPROVED</strong>.</p>")
            );
        }

        $this->renderResult($appt, 'approved');
    }

    public function reject(array $params): void
    {
        $appt = $this->findByToken($params['token'] ?? '');
        if (!$appt) { $this->renderInvalid(); return; }

        // Clear the proposal — keep original time, status stays as-is
        $appt = Container::appointments()->save(array_merge($appt, [
            'proposed_start_at' => null,
            'proposed_end_at'   => null,
            'reschedule_token'  => null,
            'reschedule_reason' => null,
        ]));
        Container::audit()->log('CUSTOMER', 'REJECT_RESCHEDULE', 'appointment', $appt['id']);

        // Notify staff
        $customer = !empty($appt['customer_id']) ? Container::users()->find($appt['customer_id']) : null;
        $notify = config('mail.notify_email');
        if ($notify && $customer) {
            $name = trim(($customer['first_name'] ?? '') . ' ' . ($customer['last_name'] ?? ''));
            Email::send($notify,
                "❌ Reschedule declined by {$name}",
                Email::template('Reschedule declined',
                    "<p><strong>{$name}</strong> has declined the proposed new time. The original appointment time remains unchanged.</p><p>The customer may want to pick a different time — please reach out to them.</p>")
            );
        }

        $this->renderResult($appt, 'rejected');
    }

    private function findByToken(string $token): ?array
    {
        if (!$token) return null;
        $all = Container::appointments()->all();
        foreach ($all as $a) {
            if (($a['reschedule_token'] ?? '') === $token) return $a;
        }
        return null;
    }

    private function renderResult(array $appt, string $action): void
    {
        $customer = !empty($appt['customer_id']) ? Container::users()->find($appt['customer_id']) : null;
        render('public', 'reschedule.result', compact('appt', 'customer', 'action'), t('reschedule.' . $action . '_title'));
    }

    private function renderInvalid(): void
    {
        render('public', 'reschedule.invalid', [], t('reschedule.invalid_title'));
    }

    private function renderConflict(array $appt): void
    {
        $customer = !empty($appt['customer_id']) ? Container::users()->find($appt['customer_id']) : null;
        render('public', 'reschedule.conflict', compact('appt', 'customer'), t('reschedule.conflict_title'));
    }
}
