<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Http\Requests\Admin\StoreShowRequest;
use App\Http\Requests\Admin\UpdateShowRequest;
use App\Models\Show;
use App\Services\ActivityLogService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Inertia\Inertia;
use Inertia\Response;

class ShowController extends Controller
{
    public function __construct(
        protected ActivityLogService $activityLogService
    ) {}

    /**
     * Display a listing of the shows.
     */
    public function index(Request $request): Response
    {
        $query = Show::query();

        // Filter by type
        $type = $request->get('type');
        if ($type && $type !== 'all') {
            $query->where('type', $type);
        }

        // Filter by status
        $status = $request->get('status');
        if ($status === 'active') {
            $query->where('is_active', true);
        } elseif ($status === 'inactive') {
            $query->where('is_active', false);
        } elseif ($status === 'live') {
            $query->where('is_live', true);
        } elseif ($status === 'replay') {
            $query->where('is_replay', true);
        }

        // Search by title, showId, or slug_live
        $search = $request->get('search');
        if ($search) {
            $query->where(function ($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                    ->orWhere('showId', 'like', "%{$search}%")
                    ->orWhere('slug_live', 'like', "%{$search}%");
            });
        }

        $perPage = min($request->get('per_page', 15), 100);
        $shows = $query->latest()->paginate($perPage)->withQueryString();

        return Inertia::render('Admin/Shows/Index', [
            'shows' => $shows->items(),
            'pagination' => [
                'data' => $shows->items(),
                'current_page' => $shows->currentPage(),
                'last_page' => $shows->lastPage(),
                'per_page' => $shows->perPage(),
                'total' => $shows->total(),
                'links' => $shows->linkCollection()->toArray(),
            ],
            'filters' => [
                'type' => $type ?? 'all',
                'status' => $status ?? 'all',
                'search' => $search ?? '',
            ],
        ]);
    }

    /**
     * Store a newly created show in storage.
     */
    public function store(StoreShowRequest $request): RedirectResponse
    {
        $data = $request->validated();

        $show = Show::create($data);

        // Log activity
        $this->activityLogService->logCreate(
            $show,
            "Created show: {$show->title} ({$show->showId})",
            ['type' => $show->type, 'price' => $show->price]
        );

        return redirect()->route('admin.shows.index')->with('success', 'Show berhasil ditambahkan.');
    }

    /**
     * Update the specified show in storage.
     */
    public function update(UpdateShowRequest $request, Show $show): RedirectResponse
    {
        $data = $request->validated();

        // Store old values for comparison
        $oldValues = $show->getOriginal();
        $show->update($data);
        $newValues = $show->fresh()->toArray();

        // Log activity
        $this->activityLogService->logUpdate(
            $show,
            "Updated show: {$show->title} ({$show->showId})",
            [
                'old_values' => $oldValues,
                'new_values' => $newValues,
            ]
        );

        return redirect()->route('admin.shows.index')->with('success', 'Show berhasil diupdate.');
    }

    /**
     * Remove the specified show from storage.
     */
    public function destroy(Show $show): RedirectResponse
    {
        // Store show data before deletion
        $showData = [
            'title' => $show->title,
            'showId' => $show->showId,
            'type' => $show->type,
        ];

        // Log activity before deletion
        $this->activityLogService->logDelete(
            $show,
            "Deleted show: {$show->title} ({$show->showId})",
            $showData
        );

        $show->delete();

        return redirect()->route('admin.shows.index')->with('success', 'Show berhasil dihapus.');
    }

    /**
     * Sync upcoming shows from external API (create new shows).
     */
    public function syncUpcoming(Request $request): JsonResponse|RedirectResponse
    {
        try {
            $eventsUrl = 'https://api.crstlnz.my.id/api/event';
            $response = Http::timeout(60)->get($eventsUrl);

            if (! $response->successful()) {
                if ($request->wantsJson()) {
                    return response()->json([
                        'success' => false,
                        'message' => 'Gagal mengambil data dari external API.',
                        'error' => $response->body(),
                    ], 500);
                }

                return redirect()->route('admin.shows.index')->with('error', 'Gagal mengambil data dari external API.');
            }

            $eventsData = $response->json();
            $upcoming = $eventsData['theater']['upcoming'] ?? [];

            if (empty($upcoming)) {
                if ($request->wantsJson()) {
                    return response()->json([
                        'success' => true,
                        'message' => 'Tidak ada upcoming shows dari external API.',
                        'total' => 0,
                        'created' => 0,
                        'skipped' => 0,
                        'results' => [],
                    ]);
                }

                return redirect()->route('admin.shows.index')->with('info', 'Tidak ada upcoming shows dari external API.');
            }

            $results = [];
            $created = 0;
            $skipped = 0;

            foreach ($upcoming as $item) {
                $showId = (string) $item['id'];
                try {
                    // Check if show already exists
                    $exists = Show::where('showId', $showId)->first();
                    if ($exists) {
                        $skipped += 1;
                        $results[] = ['showId' => $showId, 'status' => 'skipped', 'reason' => 'already_exists'];

                        continue;
                    }

                    // Get detail from external API
                    $detailUrl = "https://api.crstlnz.my.id/api/theater/{$showId}";
                    $detailResponse = Http::timeout(15)->get($detailUrl);

                    if (! $detailResponse->successful()) {
                        $skipped += 1;
                        $results[] = ['showId' => $showId, 'status' => 'skipped', 'reason' => 'detail_not_found'];

                        continue;
                    }

                    $detailData = $detailResponse->json();
                    $showDetail = $detailData['shows'][0] ?? null;

                    if (! $showDetail) {
                        $skipped += 1;
                        $results[] = ['showId' => $showId, 'status' => 'skipped', 'reason' => 'detail_not_found'];

                        continue;
                    }

                    $idn = $showDetail['idnTheater'] ?? [];
                    $setlist = $showDetail['setlist'] ?? [];
                    $members = is_array($showDetail['members'] ?? null) ? $showDetail['members'] : [];

                    // Determine type and price (same logic as TheaterController.js)
                    $titleRaw = $showDetail['title'] ?? $item['title'] ?? '';
                    $titleNorm = strtolower(trim($titleRaw));
                    $hasSeitansai = ! empty($showDetail['seitansai']) && is_array($showDetail['seitansai']);
                    $hasGraduation = ! empty($showDetail['graduation']) && is_array($showDetail['graduation']);

                    $computedType = 'Regular';
                    $computedPrice = 15000;

                    if ($titleNorm === 'pajama drive' || $titleNorm === 'ingin bertemu') {
                        $computedType = 'Trainee';
                        $computedPrice = 10000;
                    }

                    if ($hasSeitansai) {
                        $computedType = 'Birthday';
                        $computedPrice = 20000;
                    }

                    if ($hasGraduation) {
                        $computedType = 'Graduate';
                        $computedPrice = 25000;
                    }

                    // Calculate start_time
                    $startTime = null;
                    if (! empty($idn['start_at'])) {
                        $startTime = (int) $idn['start_at'];
                    } elseif (! empty($item['date'])) {
                        $startTime = (int) (strtotime($item['date']));
                    }

                    // Validate start_time
                    if ($startTime === null || $startTime <= 0) {
                        $skipped += 1;
                        $results[] = ['showId' => $showId, 'status' => 'skipped', 'reason' => 'invalid_start_time'];

                        continue;
                    }

                    // Convert price to coin_price (1 coin = 1000 rupiah)
                    $coinPrice = (int) ($computedPrice / 1000);

                    // Map external data to Show model fields
                    $showData = [
                        'showId' => $showId,
                        'title' => $showDetail['title'] ?? $item['title'] ?? 'Untitled',
                        'description' => $setlist['description'] ?? null,
                        'lineup' => array_map(function ($m) {
                            return [
                                'id' => $m['id'] ?? null,
                                'name' => $m['name'] ?? '',
                                'img' => $m['img'] ?? '',
                                'url_key' => $m['url_key'] ?? '',
                            ];
                        }, $members),
                        'seitansai' => is_array($showDetail['seitansai'] ?? null) ? $showDetail['seitansai'] : [],
                        'graduation' => is_array($showDetail['graduation'] ?? null) ? $showDetail['graduation'] : [],
                        'start_time' => $startTime,
                        'type' => $computedType,
                        'price' => $computedPrice,
                        'coin_price' => $coinPrice,
                        'banner_link' => $setlist['banner'] ?? $item['banner'] ?? null,
                        'is_promo' => false,
                        'promo_price' => null,
                        'promo_coin_price' => null,
                        'is_active' => true,
                        'is_live' => false,
                        'is_replay' => false,
                        'streamer_live' => $idn['uuid'] ?? '',
                        'slug_live' => $idn['slug'] ?? '',
                        'url_live' => null,
                        'url_replay' => null,
                        'type_live' => 'idn',
                    ];

                    // Create show
                    try {
                        $createdShow = Show::create($showData);
                        $created += 1;

                        // Log activity
                        $this->activityLogService->logCreate(
                            $createdShow,
                            "Created show from external API: {$createdShow->title} ({$createdShow->showId})",
                            [
                                'type' => $createdShow->type,
                                'price' => $createdShow->price,
                                'coin_price' => $createdShow->coin_price,
                            ]
                        );

                        $results[] = ['showId' => $showId, 'status' => 'created', 'id' => $createdShow->id, 'title' => $createdShow->title];
                    } catch (\Illuminate\Database\QueryException $dbException) {
                        \Log::error('Database error creating show', [
                            'showId' => $showId,
                            'message' => $dbException->getMessage(),
                            'showData' => $showData,
                        ]);
                        $skipped += 1;
                        $results[] = ['showId' => $showId, 'status' => 'error', 'reason' => 'Database error: '.$dbException->getMessage()];
                    }
                } catch (\Exception $e) {
                    \Log::error('Error syncing a show', [
                        'showId' => $showId,
                        'message' => $e->getMessage(),
                        'trace' => $e->getTraceAsString(),
                    ]);
                    $skipped += 1;
                    $results[] = ['showId' => $showId, 'status' => 'error', 'reason' => $e->getMessage()];
                }
            }

            $resultData = [
                'total' => count($upcoming),
                'created' => $created,
                'skipped' => $skipped,
                'results' => $results,
            ];

            // Log activity
            $this->activityLogService->logCreate(
                new Show,
                'Synced upcoming shows from external API',
                $resultData
            );

            if ($request->wantsJson()) {
                return response()->json([
                    'success' => true,
                    'message' => 'Sync berhasil dilakukan.',
                    'data' => $resultData,
                ]);
            }

            return redirect()->route('admin.shows.index')->with([
                'success' => 'Sync berhasil dilakukan.',
                'sync_result' => $resultData,
            ]);
        } catch (\Exception $e) {
            \Log::error('Error syncing upcoming shows', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            if ($request->wantsJson()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Gagal melakukan sync: '.$e->getMessage(),
                ], 500);
            }

            return redirect()->route('admin.shows.index')->with('error', 'Gagal melakukan sync: '.$e->getMessage());
        }
    }
}
