<?php

namespace App\Http\Controllers\Admin;

use App\Core\Services\Receipt\ReceiptPdfService;
use App\Core\Services\Receipt\ReceiptService;
use App\Http\Controllers\Controller;
use App\Models\CompanySetting;
use App\Models\Receipt;
use App\Support\ReceiptTemplateResolver;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Mail;
use Illuminate\Support\Facades\Storage;
use Illuminate\Support\Str;
use Illuminate\View\View;

class ReceiptController extends Controller
{
    public function __construct(
        private ReceiptService $receiptService,
        private ReceiptPdfService $receiptPdfService
    ) {}

    /**
     * Display a listing of receipts
     */
    public function index(Request $request): View
    {
        $this->authorize('viewAny', Receipt::class);

        $query = Receipt::with(['invoice', 'customer', 'creator'])
            ->orderBy('created_at', 'desc');

        if ($request->filled('search')) {
            $search = $request->get('search');
            $query->where(function ($q) use ($search) {
                $q->where('receipt_number', 'like', "%{$search}%")
                    ->orWhereHas('invoice', function ($q) use ($search) {
                        $q->where('invoice_number', 'like', "%{$search}%");
                    })
                    ->orWhereHas('customer', function ($q) use ($search) {
                        $q->where('name', 'like', "%{$search}%")
                            ->orWhere('email', 'like', "%{$search}%");
                    });
            });
        }

        if ($request->filled('date_from')) {
            $query->whereDate('created_at', '>=', $request->get('date_from'));
        }

        if ($request->filled('date_to')) {
            $query->whereDate('created_at', '<=', $request->get('date_to'));
        }

        $receipts = $query->paginate(15);

        return view('admin.receipts.index', [
            'receipts' => $receipts,
        ]);
    }

    /**
     * Display the specified receipt
     */
    public function show(Request $request, Receipt $receipt): View
    {
        $this->authorize('view', $receipt);

        $receipt->load(['invoice', 'customer', 'creator']);

        $templateKey = ReceiptTemplateResolver::resolveKeyForPreview($receipt, $request->query('template'));
        $templateView = ReceiptTemplateResolver::webView($templateKey);
        $payment = ReceiptPdfService::mapToPayment($receipt);

        $whatsappConfig = \App\Models\WhatsAppConfiguration::getActive();
        $whatsappSettings = \App\Models\WhatsAppConfiguration::query()->latest('id')->first();
        $emailConfig = \App\Models\EmailConfiguration::getActive();

        return view('admin.receipts.show', [
            'receipt' => $receipt,
            'templateView' => $templateView,
            'templateKey' => $templateKey,
            'payment' => $payment,
            'whatsappConfig' => $whatsappConfig,
            'whatsappSettings' => $whatsappSettings,
            'emailConfig' => $emailConfig,
        ]);
    }

    /**
     * Store a newly created receipt
     */
    public function store(Request $request): RedirectResponse
    {
        $this->authorize('viewAny', Receipt::class);

        $validated = $request->validate([
            'invoice_id' => 'required|exists:invoices,id',
            'payment_method' => 'nullable|string|max:255',
            'transaction_reference' => 'nullable|string|max:255',
            'notes' => 'nullable|string',
        ]);

        try {
            $receipt = $this->receiptService->create($validated);

            return redirect()
                ->route('admin.receipts.show', $receipt)
                ->with('success', 'Receipt generated successfully.');
        } catch (\Exception $e) {
            return redirect()
                ->back()
                ->withInput()
                ->withErrors(['error' => $e->getMessage()]);
        }
    }

    /**
     * Download receipt as PDF (branded templates or ?simple=1 for minimal layout).
     */
    public function downloadPdf(Request $request, Receipt $receipt)
    {
        $this->authorize('downloadPdf', $receipt);

        $receipt->load(['invoice', 'customer']);
        if ($request->boolean('simple')) {
            return $this->receiptPdfService->download($receipt, null, true);
        }

        $q = $request->query('template');
        $override = (is_string($q) && $q !== '') ? $q : null;

        return $this->receiptPdfService->download($receipt, $override, false);
    }

    /**
     * Print-friendly page (new tab).
     */
    public function printView(Request $request, Receipt $receipt): View
    {
        $this->authorize('view', $receipt);

        $receipt->load(['invoice', 'customer']);
        $templateKey = ReceiptTemplateResolver::resolveKeyForPreview($receipt, $request->query('template'));
        $templateView = ReceiptTemplateResolver::webView($templateKey);
        $payment = ReceiptPdfService::mapToPayment($receipt);

        return view('admin.receipts.print', [
            'receipt' => $receipt,
            'templateView' => $templateView,
            'payment' => $payment,
        ]);
    }

    public function sendEmail(Request $request, Receipt $receipt): JsonResponse
    {
        $this->authorize('send', $receipt);

        $request->validate([
            'email' => 'required|email',
        ]);

        $emailConfig = \App\Models\EmailConfiguration::getActive();
        if (! $emailConfig || ! $emailConfig->is_active) {
            return response()->json([
                'success' => false,
                'message' => 'Email configuration is not set up. Please configure email settings first.',
            ], 400);
        }

        try {
            $receipt->loadMissing('customer');
            $pdfContent = $this->receiptPdfService->generate($receipt, null, false);
            $filename = 'receipt-'.$receipt->receipt_number.'.pdf';
            $toEmail = trim((string) $request->input('email'));
            $companySettings = CompanySetting::getSettings();

            Mail::raw(
                'Hello '.($receipt->customer->name ?? 'Customer').",\n\n".
                "Please find your receipt #{$receipt->receipt_number} attached.\n\n".
                "Thank you,\n".($companySettings->company_name ?? config('app.name')),
                function ($message) use ($toEmail, $receipt, $pdfContent, $filename) {
                    $message->to($toEmail)
                        ->subject('Receipt '.$receipt->receipt_number)
                        ->attachData($pdfContent, $filename, ['mime' => 'application/pdf']);
                }
            );

            return response()->json([
                'success' => true,
                'message' => 'Receipt sent successfully to '.$toEmail,
            ]);
        } catch (\Throwable $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to send receipt email: '.$e->getMessage(),
            ], 500);
        }
    }

    public function sendWhatsApp(Request $request, Receipt $receipt): JsonResponse
    {
        $this->authorize('send', $receipt);

        $request->validate([
            'phone' => 'nullable|string',
        ]);

        try {
            $phone = trim((string) $request->input('phone', ''));
            if ($phone === '') {
                $receipt->loadMissing('customer');
                $phone = trim((string) ($receipt->customer->phone ?? ''));
            }
            if ($phone === '') {
                return response()->json([
                    'success' => false,
                    'message' => 'No WhatsApp recipient number found. Add a phone on the customer or enter one.',
                ], 422);
            }

            $whatsappService = new \App\Core\Services\WhatsAppService;

            $t = $request->input('template');
            $templateOverride = (is_string($t) && $t !== '') ? $t : null;
            $pdfContent = $this->receiptPdfService->generate($receipt, $templateOverride, false);
            $filename = 'receipts/receipt_'.$receipt->receipt_number.'_'.time().'.pdf';
            Storage::disk('public')->put($filename, $pdfContent);
            $documentUrl = Storage::disk('public')->url($filename);

            $companySettings = CompanySetting::getSettings();
            $receipt->load('customer', 'invoice');
            $message = 'Hello '.($receipt->customer->name ?? 'Customer').",\n\n";
            $message .= "Your payment receipt #{$receipt->receipt_number} is attached.\n\n";
            if ($receipt->invoice) {
                $message .= 'Invoice: '.$receipt->invoice->invoice_number."\n";
            }
            $pay = ReceiptPdfService::mapToPayment($receipt);
            $message .= 'Amount: '.number_format((float) $receipt->amount, 2).' '.$pay->currency."\n\n";
            $message .= "Thank you,\n".($companySettings->company_name ?? config('app.name'));

            $result = $whatsappService->send($phone, $message, $documentUrl, 'document');

            if ($result['success']) {
                return response()->json([
                    'success' => true,
                    'message' => 'Receipt PDF sent via WhatsApp to '.$phone,
                ]);
            }

            return response()->json([
                'success' => false,
                'message' => $result['message'],
            ], 400);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to send receipt via WhatsApp: '.$e->getMessage(),
            ], 500);
        }
    }

    public function getShareLink(Receipt $receipt): JsonResponse
    {
        $this->authorize('view', $receipt);

        if (empty($receipt->public_token)) {
            $receipt->public_token = Str::random(32);
            $receipt->save();
        }

        $publicBase = trim((string) config('invoice.public_base_url', ''));
        $shareLink = $publicBase !== ''
            ? rtrim($publicBase, '/').'/receipt/'.$receipt->public_token
            : route('receipt.public', ['token' => $receipt->public_token], absolute: true);

        return response()->json([
            'success' => true,
            'link' => $shareLink,
        ]);
    }
}
