<?php

namespace App\Http\Controllers\Api\V1\Admin;

use App\Http\Controllers\Controller;
use App\Models\FlashSale;
use App\Models\FlashSaleProduct;
use App\Models\AffiliateCommission;
use App\Models\ContactMessage;
use App\Models\CustomPage;
use App\Models\Partner;
use App\Models\Testimonial;
use App\Models\Setting;
use App\Jobs\MassNotificationJob;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;

class AdminFeaturesController extends Controller
{
    /* -------------------------------------------------------------------------- */
    /* 1. Mass Notification                                                       */
    /* -------------------------------------------------------------------------- */
    public function sendMassNotification(Request $request)
    {
        if (!$request->has('channels')) {
            $channels = [];
            if ($request->boolean('whatsapp')) {
                $channels[] = 'whatsapp';
            }
            if ($request->boolean('email')) {
                $channels[] = 'email';
            }
            $request->merge(['channels' => $channels]);
        }

        if (!$request->has('title')) {
            $request->merge(['title' => 'Pengumuman Toko']);
        }

        if (!$request->has('target')) {
            $request->merge(['target' => 'all']);
        }

        $request->validate([
            'title' => 'required|string|max:255',
            'message' => 'required|string',
            'channels' => 'required|array|min:1',
            'target' => 'required|string|in:all,customers,admins'
        ]);

        @set_time_limit(0);

        MassNotificationJob::dispatchSync(
            $request->title,
            $request->message,
            $request->channels,
            $request->target
        );

        return response()->json([
            'success' => true,
            'message' => 'Notifikasi massal berhasil dikirim.'
        ]);
    }

    /* -------------------------------------------------------------------------- */
    /* 2. Popup Settings                                                          */
    /* -------------------------------------------------------------------------- */
    public function updatePopupSettings(Request $request)
    {
        $request->validate([
            'popup_status' => 'required|string|in:active,inactive',
            'popup_delay' => 'required|integer|min:0',
            'popup_link' => 'nullable|string|max:255',
            'popup_image' => 'nullable' // could be file or string url
        ]);

        Setting::set('popup_status', $request->popup_status);
        Setting::set('popup_delay', $request->popup_delay);
        Setting::set('popup_link', $request->popup_link);

        if ($request->hasFile('popup_image')) {
            $path = $request->file('popup_image')->store('popups', 'public');
            Setting::set('popup_image', asset('storage/' . $path));
        } elseif ($request->has('popup_image') && $request->input('popup_image') === null) {
            Setting::set('popup_image', '');
        }

        return response()->json([
            'success' => true,
            'message' => 'Pengaturan popup beranda berhasil diperbarui.'
        ]);
    }

    /* -------------------------------------------------------------------------- */
    /* 3. Flash Sales CRUD                                                        */
    /* -------------------------------------------------------------------------- */
    public function getFlashSales()
    {
        $flashSales = FlashSale::with(['products.product.variants', 'products.variant'])->latest()->get();
        return response()->json(['success' => true, 'flash_sales' => $flashSales]);
    }

    public function storeFlashSale(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'start_time' => 'required|date',
            'end_time' => 'required|date|after:start_time',
            'is_active' => 'required|boolean',
            'products' => 'required|array|min:1',
            'products.*.product_id' => 'required|exists:products,id',
            'products.*.variant_id' => 'nullable|exists:product_variants,id',
            'products.*.flash_sale_price' => 'required|numeric|min:0',
            'products.*.stock' => 'required|integer|min:1',
        ]);

        $flashSale = FlashSale::create($request->only('title', 'start_time', 'end_time', 'is_active'));

        foreach ($request->products as $p) {
            FlashSaleProduct::create([
                'flash_sale_id' => $flashSale->id,
                'product_id' => $p['product_id'],
                'variant_id' => $p['variant_id'] ?? null,
                'flash_sale_price' => $p['flash_sale_price'],
                'stock' => $p['stock'],
                'sold' => 0
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Flash sale berhasil dibuat.'
        ]);
    }

    public function updateFlashSale(Request $request, $id)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'start_time' => 'required|date',
            'end_time' => 'required|date|after:start_time',
            'is_active' => 'required|boolean',
            'products' => 'required|array|min:1',
            'products.*.product_id' => 'required|exists:products,id',
            'products.*.variant_id' => 'nullable|exists:product_variants,id',
            'products.*.flash_sale_price' => 'required|numeric|min:0',
            'products.*.stock' => 'required|integer|min:1',
        ]);

        $flashSale = FlashSale::findOrFail($id);
        $flashSale->update($request->only('title', 'start_time', 'end_time', 'is_active'));

        // Rebuild products relation
        $flashSale->products()->delete();
        foreach ($request->products as $p) {
            FlashSaleProduct::create([
                'flash_sale_id' => $flashSale->id,
                'product_id' => $p['product_id'],
                'variant_id' => $p['variant_id'] ?? null,
                'flash_sale_price' => $p['flash_sale_price'],
                'stock' => $p['stock'],
                'sold' => $p['sold'] ?? 0
            ]);
        }

        return response()->json([
            'success' => true,
            'message' => 'Flash sale berhasil diperbarui.'
        ]);
    }

    public function deleteFlashSale($id)
    {
        $flashSale = FlashSale::findOrFail($id);
        $flashSale->delete();

        return response()->json(['success' => true, 'message' => 'Flash sale berhasil dihapus.']);
    }

    /* -------------------------------------------------------------------------- */
    /* 4. Affiliate Commissions & Withdrawals                                     */
    /* -------------------------------------------------------------------------- */
    public function getAffiliateCommissions()
    {
        $commissions = AffiliateCommission::with(['user', 'buyer', 'order'])->latest()->get();
        return response()->json(['success' => true, 'commissions' => $commissions]);
    }

    public function approveAffiliateCommission(Request $request, $id)
    {
        $request->validate([
            'status' => 'required|string|in:approved,withdrawn,pending,paid'
        ]);

        $commission = AffiliateCommission::findOrFail($id);
        $commission->update(['status' => $request->status]);

        return response()->json(['success' => true, 'message' => 'Status komisi affiliate berhasil diperbarui.']);
    }

    public function getWithdrawalRequests()
    {
        $withdrawals = \App\Models\WithdrawalRequest::with('user')->latest()->get();
        return response()->json(['success' => true, 'withdrawals' => $withdrawals]);
    }

    public function updateWithdrawalStatus(Request $request, $id)
    {
        $request->validate([
            'status' => 'required|string|in:approved,rejected',
            'notes' => 'nullable|string'
        ]);

        $withdrawal = \App\Models\WithdrawalRequest::findOrFail($id);

        if ($withdrawal->status !== 'pending') {
            return response()->json([
                'success' => false,
                'message' => 'Permintaan penarikan ini sudah diproses.'
            ], 422);
        }

        \Illuminate\Support\Facades\DB::transaction(function () use ($request, $withdrawal) {
            $withdrawal->update([
                'status' => $request->status,
                'notes' => $request->notes
            ]);

            if ($request->status === 'approved') {
                // Update all linked commissions to withdrawn (which gets returned as paid via accessor)
                $withdrawal->commissions()->update(['status' => 'withdrawn']);
            } else {
                // Reset withdrawal_request_id so these commissions are withdrawable again
                $withdrawal->commissions()->update(['withdrawal_request_id' => null]);
            }
        });

        return response()->json([
            'success' => true,
            'message' => 'Status permintaan penarikan berhasil diperbarui.'
        ]);
    }

    /* -------------------------------------------------------------------------- */
    /* 5. Contact Messages (Inbox)                                                */
    /* -------------------------------------------------------------------------- */
    public function getContactMessages()
    {
        $messages = ContactMessage::latest()->get();
        return response()->json(['success' => true, 'messages' => $messages]);
    }

    public function markContactMessageRead($id)
    {
        $msg = ContactMessage::findOrFail($id);
        $msg->update(['status' => 'read']);
        return response()->json(['success' => true, 'message' => 'Pesan ditandai sudah dibaca.']);
    }

    public function deleteContactMessage($id)
    {
        $msg = ContactMessage::findOrFail($id);
        $msg->delete();
        return response()->json(['success' => true, 'message' => 'Pesan berhasil dihapus.']);
    }

    /* -------------------------------------------------------------------------- */
    /* 6. Custom Pages CRUD                                                       */
    /* -------------------------------------------------------------------------- */
    public function getCustomPages()
    {
        $pages = CustomPage::latest()->get();
        return response()->json(['success' => true, 'pages' => $pages]);
    }

    public function storeCustomPage(Request $request)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|unique:custom_pages,slug',
            'content' => 'required|string',
            'meta_title' => 'nullable|string|max:255',
            'meta_description' => 'nullable|string',
            'is_active' => 'required|boolean'
        ]);

        $page = CustomPage::create($request->all());

        return response()->json(['success' => true, 'message' => 'Halaman kustom berhasil dibuat.', 'page' => $page]);
    }

    public function updateCustomPage(Request $request, $id)
    {
        $request->validate([
            'title' => 'required|string|max:255',
            'slug' => 'required|string|unique:custom_pages,slug,' . $id,
            'content' => 'required|string',
            'meta_title' => 'nullable|string|max:255',
            'meta_description' => 'nullable|string',
            'is_active' => 'required|boolean'
        ]);

        $page = CustomPage::findOrFail($id);
        $page->update($request->all());

        return response()->json(['success' => true, 'message' => 'Halaman kustom berhasil diperbarui.', 'page' => $page]);
    }

    public function deleteCustomPage($id)
    {
        $page = CustomPage::findOrFail($id);
        $page->delete();
        return response()->json(['success' => true, 'message' => 'Halaman kustom berhasil dihapus.']);
    }

    /* -------------------------------------------------------------------------- */
    /* 7. Partner Logos CRUD                                                      */
    /* -------------------------------------------------------------------------- */
    public function getPartners()
    {
        $partners = Partner::orderBy('sort_order', 'asc')->get();
        return response()->json(['success' => true, 'partners' => $partners]);
    }

    public function storePartner(Request $request)
    {
        $logoKey = $request->hasFile('logo_path') ? 'logo_path' : 'logo';
        $linkKey = $request->has('link_url') ? 'link_url' : ($request->has('link') ? 'link' : null);

        $rules = [
            'name' => 'required|string|max:255',
            'sort_order' => 'required|integer'
        ];

        if ($logoKey) {
            $rules[$logoKey] = 'required|image|max:2048';
        } else {
            $rules['logo'] = 'required|image|max:2048';
        }

        if ($linkKey) {
            $rules[$linkKey] = 'nullable|string|max:255';
        }

        $request->validate($rules);

        $uploadedKey = $logoKey ?: 'logo';
        $path = $request->file($uploadedKey)->store('partners', 'public');

        $partner = Partner::create([
            'name' => $request->name,
            'logo' => asset('storage/' . $path),
            'link' => $linkKey ? $request->input($linkKey) : null,
            'sort_order' => $request->sort_order
        ]);

        return response()->json(['success' => true, 'message' => 'Logo mitra berhasil ditambahkan.', 'partner' => $partner]);
    }

    public function updatePartner(Request $request, $id)
    {
        $logoKey = $request->hasFile('logo_path') ? 'logo_path' : 'logo';
        $linkKey = $request->has('link_url') ? 'link_url' : ($request->has('link') ? 'link' : null);

        $rules = [
            'name' => 'required|string|max:255',
            'sort_order' => 'required|integer'
        ];

        if ($request->hasFile($logoKey)) {
            $rules[$logoKey] = 'nullable|image|max:2048';
        }

        if ($linkKey) {
            $rules[$linkKey] = 'nullable|string|max:255';
        }

        $request->validate($rules);

        $partner = Partner::findOrFail($id);
        $payload = [
            'name' => $request->name,
            'link' => $linkKey ? $request->input($linkKey) : $partner->link,
            'sort_order' => $request->sort_order
        ];

        if ($request->hasFile($logoKey)) {
            // Delete old file
            $oldFilename = basename($partner->logo);
            Storage::disk('public')->delete('partners/' . $oldFilename);

            $path = $request->file($logoKey)->store('partners', 'public');
            $payload['logo'] = asset('storage/' . $path);
        }

        $partner->update($payload);

        return response()->json(['success' => true, 'message' => 'Logo mitra berhasil diperbarui.', 'partner' => $partner]);
    }

    public function deletePartner($id)
    {
        $partner = Partner::findOrFail($id);
        $oldFilename = basename($partner->logo);
        Storage::disk('public')->delete('partners/' . $oldFilename);
        $partner->delete();

        return response()->json(['success' => true, 'message' => 'Logo mitra berhasil dihapus.']);
    }

    /* -------------------------------------------------------------------------- */
    /* 8. Testimonials CRUD                                                       */
    /* -------------------------------------------------------------------------- */
    public function getTestimonials()
    {
        $testimonials = Testimonial::latest()->get();
        return response()->json(['success' => true, 'testimonials' => $testimonials]);
    }

    public function storeTestimonial(Request $request)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'avatar' => 'nullable|image|max:1024',
            'company_or_role' => 'nullable|string|max:255',
            'rating' => 'required|integer|min:1|max:5',
            'comment' => 'required|string',
            'is_active' => 'required|boolean'
        ]);

        $avatarUrl = null;
        if ($request->hasFile('avatar')) {
            $path = $request->file('avatar')->store('testimonials', 'public');
            $avatarUrl = asset('storage/' . $path);
        }

        $testimonial = Testimonial::create([
            'name' => $request->name,
            'avatar' => $avatarUrl,
            'company_or_role' => $request->company_or_role,
            'rating' => $request->rating,
            'comment' => $request->comment,
            'is_active' => $request->is_active
        ]);

        return response()->json(['success' => true, 'message' => 'Testimoni berhasil ditambahkan.', 'testimonial' => $testimonial]);
    }

    public function updateTestimonial(Request $request, $id)
    {
        $request->validate([
            'name' => 'required|string|max:255',
            'avatar' => 'nullable',
            'company_or_role' => 'nullable|string|max:255',
            'rating' => 'required|integer|min:1|max:5',
            'comment' => 'required|string',
            'is_active' => 'required|boolean'
        ]);

        $testimonial = Testimonial::findOrFail($id);
        $payload = [
            'name' => $request->name,
            'company_or_role' => $request->company_or_role,
            'rating' => $request->rating,
            'comment' => $request->comment,
            'is_active' => $request->is_active
        ];

        if ($request->hasFile('avatar')) {
            if ($testimonial->avatar) {
                $oldFilename = basename($testimonial->avatar);
                Storage::disk('public')->delete('testimonials/' . $oldFilename);
            }
            $path = $request->file('avatar')->store('testimonials', 'public');
            $payload['avatar'] = asset('storage/' . $path);
        }

        $testimonial->update($payload);

        return response()->json(['success' => true, 'message' => 'Testimoni berhasil diperbarui.', 'testimonial' => $testimonial]);
    }

    public function deleteTestimonial($id)
    {
        $testimonial = Testimonial::findOrFail($id);
        if ($testimonial->avatar) {
            $oldFilename = basename($testimonial->avatar);
            Storage::disk('public')->delete('testimonials/' . $oldFilename);
        }
        $testimonial->delete();

        return response()->json(['success' => true, 'message' => 'Testimoni berhasil dihapus.']);
    }
}
