<?php

namespace App\Filament\Tenant\Pages;

use App\Models\Tenant\WorkOrder;
use Filament\Pages\Page;

/**
 * Mitchell1-style 3-column dashboard view for a single WorkOrder.
 * MVP Phase 1: layout + tabs (Works/Parts/Diagnostic/Photos/Docs/Notes).
 * Editing still goes through /app/work-orders/{id}/edit for now.
 */
class WorkOrderDashboard extends Page
{
    protected static string|\BackedEnum|null $navigationIcon = null;

    protected static bool $shouldRegisterNavigation = false;

    protected string $view = 'filament.tenant.pages.work-order-dashboard';

    public ?WorkOrder $record = null;

    public string $activeTab = 'works';

    public static function getSlug(?\Filament\Panel $panel = null): string
    {
        return 'work-orders/{record}/dashboard';
    }

    public static function getRoutePath(?\Filament\Panel $panel = null): string
    {
        return 'work-orders/{record}/dashboard';
    }

    public function mount(int|string $record): void
    {
        $id = (int) $record;
        $wo = WorkOrder::with([
            'client', 'vehicle', 'master',
            'works.labor', 'works.master',
            'parts.part',
            'payments.user',
            'subcontractJobs.subcontractor',
        ])->find($id);

        if (! $wo) {
            // Diagnose: does it exist in another tenant?
            $existsGlobally = WorkOrder::withoutGlobalScopes()
                ->where('id', $id)->exists();
            $tenant = app(\App\Tenancy\TenantManager::class)->current();
            $tenantSlug = $tenant?->slug ?? '—';
            $msg = $existsGlobally
                ? sprintf(__('Fișa #%d există, dar nu aparține tenantului „%s".'), $id, $tenantSlug)
                : sprintf(__('Fișa #%d nu există. Verifică lista de fișe active.'), $id);
            \Filament\Notifications\Notification::make()
                ->title(__('Fișă indisponibilă'))
                ->body($msg)
                ->danger()
                ->persistent()
                ->send();
            redirect('/app/work-orders')->send();
            exit;
        }
        $this->record = $wo;
    }

    public function setTab(string $tab): void
    {
        $this->activeTab = $tab;
    }

    public function getTitle(): string|\Illuminate\Contracts\Support\Htmlable
    {
        return __('Fișă') . ' ' . ($this->record->number ?? '');
    }

    public function getHeading(): string|\Illuminate\Contracts\Support\Htmlable
    {
        return '';
    }

    /** Latest 5 WOs for the vehicle (repair history sidebar). */
    public function getRepairHistory(): \Illuminate\Support\Collection
    {
        if (! $this->record->vehicle_id) return collect();
        return WorkOrder::where('vehicle_id', $this->record->vehicle_id)
            ->where('id', '!=', $this->record->id)
            ->orderByDesc('opened_at')
            ->limit(5)
            ->get(['id', 'number', 'opened_at', 'total', 'status']);
    }

    /**
     * Timeline events for the right panel. Synthesises events from
     * WO fields (created, opened, closed, paid, status transitions
     * captured via activity_log if the trait is added) + notifications sent.
     */
    public function getTimeline(): array
    {
        $wo = $this->record;
        $events = [];

        if ($wo->created_at) {
            $events[] = [
                'at' => $wo->created_at,
                'kind' => 'created',
                'label' => __('Fișă creată'),
                'meta' => $wo->number,
                'icon' => '📋',
            ];
        }
        if ($wo->opened_at && $wo->opened_at->ne($wo->created_at)) {
            $events[] = [
                'at' => $wo->opened_at,
                'kind' => 'opened',
                'label' => __('Auto primit în service'),
                'meta' => null,
                'icon' => '🚗',
            ];
        }
        if ($wo->approved_at) {
            $events[] = [
                'at' => $wo->approved_at,
                'kind' => 'approved',
                'label' => __('Aprobat de client'),
                'meta' => null,
                'icon' => '✓',
            ];
        }
        if ($wo->closed_at) {
            $events[] = [
                'at' => $wo->closed_at instanceof \Carbon\Carbon ? $wo->closed_at : \Carbon\Carbon::parse($wo->closed_at),
                'kind' => 'closed',
                'label' => __('Fișă închisă'),
                'meta' => null,
                'icon' => '🔒',
            ];
        }

        // Payments
        foreach ($wo->payments as $p) {
            $events[] = [
                'at' => $p->paid_at,
                'kind' => 'payment',
                'label' => __('Plată primită'),
                'meta' => number_format((float) $p->amount, 2, '.', ' ') . ' MDL · ' . __(\App\Models\Tenant\Payment::METHODS[$p->method] ?? $p->method),
                'icon' => '💰',
            ];
        }

        // Activity log (spatie/activitylog) — best-effort read
        try {
            $activities = \DB::table('activity_log')
                ->where('subject_type', WorkOrder::class)
                ->where('subject_id', $wo->id)
                ->where('company_id', $wo->company_id)
                ->orderBy('created_at')
                ->get();
            foreach ($activities as $a) {
                $events[] = [
                    'at' => \Carbon\Carbon::parse($a->created_at),
                    'kind' => $a->event ?? 'log',
                    'label' => $a->description ?: ucfirst($a->event ?? 'log'),
                    'meta' => null,
                    'icon' => '📝',
                ];
            }
        } catch (\Throwable) { /* activity_log table may be empty on fresh DB */ }

        // Sort chronologically desc so newest first
        usort($events, fn ($a, $b) => $b['at']->timestamp <=> $a['at']->timestamp);
        return $events;
    }

    /** Outbound notifications to the client (SMS/WhatsApp/Telegram/Email). */
    public function getNotifications(): \Illuminate\Support\Collection
    {
        return \App\Models\Tenant\ClientNotificationLog::where('work_order_id', $this->record->id)
            ->orderByDesc('sent_at')
            ->limit(20)
            ->get();
    }

    public string $newMessage = '';

    public function sendMessage(): void
    {
        $text = trim($this->newMessage);
        if ($text === '' || ! $this->record->client) return;

        $client = $this->record->client;
        $company = app(\App\Tenancy\TenantManager::class)->current();
        if (! $company) return;

        $dispatcher = app(\App\Services\NotificationDispatcher::class);
        $sent = false;

        // Prefer Telegram if the client is linked; fall back to WhatsApp if a phone is set.
        if (! empty($client->telegram_chat_id)) {
            try {
                $sent = app(\App\Services\Notifications\TelegramService::class)
                    ->sendMessage($company, (string) $client->telegram_chat_id, $text);
            } catch (\Throwable) { /* ignore */ }
        }

        // Log the message so it shows up in the chat pane regardless of delivery.
        \App\Models\Tenant\ClientNotificationLog::create([
            'company_id' => $company->id,
            'work_order_id' => $this->record->id,
            'client_id' => $client->id,
            'channel' => ! empty($client->telegram_chat_id) ? 'telegram' : 'sms',
            'template_key' => 'manual',
            'message_text' => $text,
            'status' => $sent ? 'sent' : 'failed',
            'sent_at' => now(),
        ]);

        $this->newMessage = '';

        \Filament\Notifications\Notification::make()
            ->title($sent ? __('Mesaj trimis') : __('Trimitere eșuată — verifică integrarea'))
            ->{$sent ? 'success' : 'warning'}()
            ->send();
    }

    /** Adjacent WOs for the previous/next buttons in the bottom bar. */
    public function getPrevWo(): ?WorkOrder
    {
        return WorkOrder::where('id', '<', $this->record->id)
            ->orderByDesc('id')
            ->first(['id', 'number']);
    }

    public function getNextWo(): ?WorkOrder
    {
        return WorkOrder::where('id', '>', $this->record->id)
            ->orderBy('id')
            ->first(['id', 'number']);
    }

    public function closeWorkOrder(): void
    {
        $wo = $this->record;
        if ($wo->status === 'done') return;
        $wo->forceFill([
            'status' => 'done',
            'closed_at' => now(),
        ])->save();
        $this->record->refresh();
        \Filament\Notifications\Notification::make()
            ->title(__('Fișă închisă'))
            ->success()->send();
    }

    /** Aggregated finance data — used by right panel in future phases. */
    public function getFinance(): array
    {
        $r = $this->record;
        $worksSum = (float) $r->works->sum('total');
        $partsSum = (float) $r->parts->sum('total');
        $subtotal = $worksSum + $partsSum;
        $discount = (float) $r->discount;
        $total = max(0, $subtotal - $discount);
        $paid = $r->paidAmount();
        return [
            'works_sum' => $worksSum,
            'parts_sum' => $partsSum,
            'subtotal' => $subtotal,
            'discount' => $discount,
            'total' => $total,
            'paid' => $paid,
            'balance' => max(0, $total - $paid),
        ];
    }
}
