<?php

namespace App\Services;

use App\Models\Diary;
use App\Models\DiaryQuickEntry;
use Illuminate\Http\Request;
use Carbon\Carbon;
use Illuminate\Support\Collection;

class DiaryService
{
    /**
     * Create a diary entry (contextual or quick)
     */
    public function create(array $data, string $type = 'contextual'): Diary|DiaryQuickEntry
    {
        $data['created_by'] = auth()->id();
        $data['updated_by'] = auth()->id();

        return match ($type) {
            'contextual' => Diary::create($data),
            'quick' => DiaryQuickEntry::create($data),
            default => throw new \InvalidArgumentException("Invalid type: {$type}")
        };
    }

    /**
     * Get combined diary entries from both tables
     */
    public function getCombinedEntries(array $filters = []): Collection
    {
        $contextualQuery = Diary::query()->withRelations();
        $quickQuery = DiaryQuickEntry::query()->with(['assignedUser']);

        // Apply shared filters
        $this->applyFilters($contextualQuery, $filters);
        $this->applyFilters($quickQuery, $filters);

        $contextual = $contextualQuery->get();
        $quick = $quickQuery->get();

        $merged = $contextual->merge($quick)
            ->sortByDesc(function ($entry) {
                return $entry->date_time ?? $entry->entry_date ?? '1900-01-01';
            })
            ->values();

        return $merged->map(function ($entry) {
            $type = $entry instanceof \App\Models\Diary ? 'contextual' : 'quick';
            return $this->normalizeEntry($entry, $type);
        });
    }

    /**
     * Find entry by ID and type
     */
    public function find(int $id, string $type): Diary|DiaryQuickEntry|null
    {
        return match ($type) {
            'contextual' => Diary::withRelations()->find($id),
            'quick' => DiaryQuickEntry::find($id),
            default => null
        };
    }

    /**
     * Update entry
     */
    public function update(int $id, array $data, string $type): bool
    {
        $data['updated_by'] = auth()->id();
        $entry = $this->find($id, $type);

        if (!$entry) {
            return false;
        }

        return $entry->update($data);
    }

    /**
     * Delete entry
     */
    public function delete(int $id, string $type): bool
    {
        $entry = $this->find($id, $type);
        return $entry ? $entry->delete() : false;
    }

    /**
     * Apply filters to query
     */
    private function applyFilters($query, array $filters): void
    {
        $model = $query->getModel();
        $table = $model->getTable();
        $dateField = $table === 'diary_quick_entries' ? 'entry_date' : 'date_time';

        // Status filter (Diary only)
        if (isset($filters['status']) && $model instanceof Diary) {
            $query->where('status', $filters['status']);
        }

        // Status filter for quick entries (mapped via is_completed)
        if (isset($filters['status']) && $model instanceof DiaryQuickEntry) {
            $status = (string) $filters['status'];
            if ($status === 'completed') {
                $query->where('is_completed', true);
            } elseif ($status === 'pending') {
                $query->where('is_completed', false);
            }
        }

        // Priority filter (Diary only)
        if (isset($filters['priority']) && $model instanceof Diary) {
            $query->where('priority', $filters['priority']);
        }

        // Task type filter (both)
        if (isset($filters['task_type'])) {
            $query->where('task_type', $filters['task_type']);
        }

        // Date range - use dynamic field name
        if (isset($filters['start_date'])) {
            $query->whereDate($dateField, '>=', $filters['start_date']);
        }
        if (isset($filters['end_date'])) {
            $query->whereDate($dateField, '<=', $filters['end_date']);
        }

        // Today
        if (isset($filters['today'])) {
            $query->whereDate($dateField, Carbon::today());
        }

        // Upcoming (Diary only - has status)
        if (isset($filters['upcoming']) && $model instanceof Diary) {
            $query->where($dateField, '>', now())
                  ->where('status', '!=', 'completed');
        }

        // Overdue (Diary only - has status)
        if (isset($filters['overdue']) && $model instanceof Diary) {
            $query->where($dateField, '<', now())
                  ->whereNotIn('status', ['completed', 'deferred']);
        }
    }

    /**
     * Normalize entry for unified display
     */
    private function normalizeEntry($entry, ?string $type = null): array
    {
        if ($type === null) {
            $type = $entry instanceof \App\Models\Diary ? 'contextual' : 'quick';
        }

        $entryDate = $entry->date_time ?? $entry->entry_date;
        $isContextual = $type === 'contextual';

        $priority = $isContextual ? ($entry->priority ?? 'medium') : 'medium';
        $isCompleted = (bool) ($entry->is_completed ?? false);

        $status = $isContextual ? ($entry->status ?? 'pending') : 'pending';
        if ($isCompleted) {
            $status = 'completed';
        }

        return [
            'id' => $entry->id,
            'type' => $type,
            'entry_date' => $entryDate,
            'formatted_date' => $entryDate ? $entryDate->format('d M Y') : '—',
            'formatted_time' => $entryDate && $isContextual ? $entryDate->format('H:i') : '—',
            'title' => $entry->task_title,
            'client_case' => $isContextual ? ($entry->client_case ?? null) : null,
            'task_type' => $entry->task_type ?? null,
            'priority' => $priority,
            'status' => $status,
            'is_completed' => $isCompleted,
            'completed_at' => $entry->completed_at ?? null,
            'location' => $isContextual ? ($entry->location ?? null) : null,
            'duration_formatted' => $isContextual ? ($entry->duration_formatted ?? '—') : '—',
            'notes' => $entry->notes,
            'assigned_to' => $entry->assigned_to,
            'created_by' => $entry->created_by,
            'updated_at' => $entry->updated_at,
            'raw_entry' => $entry, // For further processing
        ];
    }

    /**
     * Get dashboard stats (combined)
     */
    public function getDashboardStats(): array
    {
        $todayDate = Carbon::today();

        $contextualStats = \DB::table('diary_contextual_entries')
            ->selectRaw('
                COUNT(*) as total,
                SUM(CASE WHEN status = "completed" THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN date_time >= ? THEN 1 ELSE 0 END) as today
            ', [$todayDate])
            ->first();

        $quickStats = \DB::table('diary_quick_entries')
            ->selectRaw('
                COUNT(*) as total, 
                SUM(CASE WHEN is_completed = 1 THEN 1 ELSE 0 END) as completed, 
                SUM(CASE WHEN DATE(entry_date) = ? THEN 1 ELSE 0 END) as today
            ', [$todayDate->toDateString()])
            ->first();

        return [
            'total' => ($contextualStats->total ?? 0) + ($quickStats->total ?? 0),
            'today' => ($contextualStats->today ?? 0) + ($quickStats->today ?? 0),
            'completed' => ($contextualStats->completed ?? 0) + ($quickStats->completed ?? 0),
        ];
    }
}

