<?php

declare(strict_types=1);

namespace common\services;

use common\models\DietPlan;
use common\models\DietPlanMeal;
use common\models\Invoice;
use Mpdf\Mpdf;
use Mpdf\MpdfException;

/**
 * PdfService — generates Invoice PDF and Diet Plan PDF using mPDF.
 */
class PdfService
{
    /**
     * Generate Invoice PDF and return as string or stream to browser.
     *
     * @throws MpdfException
     */
    public function generateInvoicePdf(Invoice $invoice, bool $download = true): void
    {
        $invoice->populateRelation('customer', $invoice->customer);
        $invoice->populateRelation('items', $invoice->items);

        $html = $this->renderInvoiceHtml($invoice);

        $mpdf = new Mpdf([
            'mode'        => 'utf-8',
            'format'      => 'A4',
            'orientation' => 'P',
            'margin_top'  => 15,
            'margin_left' => 15,
            'margin_right'=> 15,
            'tempDir'     => dirname(dirname(__DIR__)) . '/backend/runtime/mpdf',
        ]);

        $mpdf->SetTitle('Invoice ' . $invoice->invoice_number);
        $mpdf->WriteHTML($html);

        $filename = 'Invoice-' . $invoice->invoice_number . '.pdf';
        $dest     = $download ? 'D' : 'I';
        $mpdf->Output($filename, $dest);
    }

    /**
     * Generate Diet Plan PDF.
     *
     * @throws MpdfException
     */
    public function generateDietPlanPdf(DietPlan $plan, bool $download = true): void
    {
        $plan->populateRelation('customer', $plan->customer);
        $plan->populateRelation('meals', $plan->meals);

        $html = $this->renderDietPlanHtml($plan);

        $mpdf = new Mpdf([
            'mode'        => 'utf-8',
            'format'      => 'A4',
            'orientation' => 'P',
            'margin_top'  => 15,
            'margin_left' => 12,
            'margin_right'=> 12,
            'tempDir'     => dirname(dirname(__DIR__)) . '/backend/runtime/mpdf',
        ]);

        $mpdf->SetTitle('Diet Plan - ' . $plan->title);
        $mpdf->WriteHTML($html);

        $filename = 'DietPlan-' . $plan->id . '.pdf';
        $dest     = $download ? 'D' : 'I';
        $mpdf->Output($filename, $dest);
    }

    /**
     * Returns an <img> tag with logo embedded as base64, or text fallback if file missing.
     */
    private function logoHtml(int $height = 50): string
    {
        $logoPath = dirname(dirname(__DIR__)) . '/backend/web/img/logo.png';
        if (file_exists($logoPath)) {
            $data = base64_encode(file_get_contents($logoPath));
            return "<img src='data:image/png;base64,{$data}' style='height:{$height}px;vertical-align:middle'>";
        }
        return "<span style='font-size:22px;font-weight:bold;color:white'>SJ Nutrizione</span>";
    }

    private function renderInvoiceHtml(Invoice $invoice): string
    {
        $customer = $invoice->customer;
        $items    = $invoice->items;

        $rows = '';
        foreach ($items as $item) {
            $rows .= "<tr>
                <td style='padding:8px'>" . htmlspecialchars($item->description) . "</td>
                <td style='text-align:center;padding:8px'>" . (float)$item->quantity . "</td>
                <td style='text-align:right;padding:8px'>&#8377;" . number_format((float)$item->unit_price, 2) . "</td>
                <td style='text-align:right;padding:8px'>&#8377;" . number_format((float)$item->total_price, 2) . "</td>
            </tr>";
        }

        $status     = strtoupper($invoice->status);
        $statusColor= ['PAID' => '#22c55e', 'UNPAID' => '#ef4444', 'PARTIAL' => '#f59e0b', 'CANCELLED' => '#94a3b8'][$status] ?? '#94a3b8';

        return "
        <style>
            body { font-family: Arial, sans-serif; font-size: 12px; color: #1e293b; }
            .header { background: #1a2035; color: white; padding: 20px; margin-bottom: 20px; }
            .header h1 { margin: 0; font-size: 22px; }
            .header small { opacity: 0.7; font-size: 11px; }
            table { width: 100%; border-collapse: collapse; }
            thead th { background: #f1f5f9; padding: 8px; text-align: left; border-bottom: 2px solid #e2e8f0; }
            .totals td { padding: 6px 8px; }
            .badge { display: inline-block; padding: 4px 10px; border-radius: 4px; font-size: 11px; font-weight: bold; color: white; }
        </style>

        <div class='header'>
            <table style='width:100%;border:0'>
                <tr>
                    <td style='width:70px;vertical-align:middle'>" . $this->logoHtml(55) . "</td>
                    <td style='vertical-align:middle;padding-left:12px'>
                        <div style='font-size:20px;font-weight:bold;color:white'>SJ Nutrizione</div>
                        <div style='font-size:11px;color:rgba(255,255,255,0.7)'>Sports &bull; Nutrigenomics &bull; Clinical</div>
                    </td>
                    <td style='text-align:right;vertical-align:middle;color:rgba(255,255,255,0.8);font-size:11px'>
                        TAX INVOICE
                    </td>
                </tr>
            </table>
        </div>

        <table style='margin-bottom:20px'>
            <tr>
                <td style='width:60%'>
                    <strong>Bill To:</strong><br>
                    " . htmlspecialchars($customer?->name ?? 'N/A') . "<br>
                    " . htmlspecialchars($customer?->phone ?? '') . "<br>
                    " . ($customer?->gst_number ? "GST: " . htmlspecialchars($customer->gst_number) : '') . "
                </td>
                <td style='text-align:right'>
                    <div style='font-size:18px;font-weight:bold'>" . htmlspecialchars($invoice->invoice_number) . "</div>
                    <div>Date: " . $invoice->invoice_date . "</div>
                    " . ($invoice->due_date ? "<div>Due: " . $invoice->due_date . "</div>" : '') . "
                    <div><span class='badge' style='background:{$statusColor}'>{$status}</span></div>
                </td>
            </tr>
        </table>

        <table style='margin-bottom:20px'>
            <thead><tr><th>Description</th><th style='text-align:center'>Qty</th><th style='text-align:right'>Rate</th><th style='text-align:right'>Amount</th></tr></thead>
            <tbody>{$rows}</tbody>
        </table>

        <table class='totals' style='width:45%;margin-left:55%'>
            <tr><td>Subtotal</td><td style='text-align:right'>&#8377;" . number_format((float)$invoice->subtotal, 2) . "</td></tr>
            <tr><td>GST (" . (float)$invoice->gst_rate . "%)</td><td style='text-align:right'>&#8377;" . number_format((float)$invoice->gst_amount, 2) . "</td></tr>
            " . ((float)$invoice->discount_amount > 0 ? "<tr><td>Discount</td><td style='text-align:right;color:#ef4444'>-&#8377;" . number_format((float)$invoice->discount_amount, 2) . "</td></tr>" : '') . "
            <tr style='background:#f1f5f9;font-weight:bold'>
                <td style='padding:8px'>Total</td>
                <td style='text-align:right;font-size:16px;padding:8px'>&#8377;" . number_format((float)$invoice->total_amount, 2) . "</td>
            </tr>
            <tr><td style='color:#22c55e'>Paid</td><td style='text-align:right;color:#22c55e'>&#8377;" . number_format((float)$invoice->paid_amount, 2) . "</td></tr>
            <tr><td style='color:#ef4444;font-weight:bold'>Outstanding</td><td style='text-align:right;color:#ef4444;font-weight:bold'>&#8377;" . number_format($invoice->getOutstandingAmount(), 2) . "</td></tr>
        </table>

        " . ($invoice->notes ? "<p style='margin-top:20px;color:#64748b;font-size:11px'><strong>Notes:</strong> " . htmlspecialchars($invoice->notes) . "</p>" : '') . "

        <div style='margin-top:40px;text-align:center;color:#94a3b8;font-size:10px'>
            Thank you for choosing SJ Nutrizione &bull; Generated on " . date('d M Y') . "
        </div>";
    }

    private function renderDietPlanHtml(DietPlan $plan): string
    {
        $customer   = $plan->customer;
        $mealLabels = DietPlanMeal::mealTypeLabels();
        $mealsByType = [];
        foreach ($plan->meals as $meal) {
            $mealsByType[$meal->meal_type][] = $meal;
        }

        $mealsHtml = '';
        foreach (DietPlan::mealTypeOrder() as $mealType) {
            if (!isset($mealsByType[$mealType])) continue;

            $rows = '';
            foreach ($mealsByType[$mealType] as $meal) {
                $rows .= "<tr>
                    <td style='padding:6px'>" . htmlspecialchars($meal->getDisplayName()) . "</td>
                    <td style='text-align:center;padding:6px'>" . (float)$meal->quantity . " " . $meal->unit . "</td>
                    <td style='text-align:right;padding:6px'>" . number_format((float)$meal->calories, 0) . "</td>
                    <td style='text-align:right;padding:6px'>" . number_format((float)$meal->protein, 1) . "g</td>
                    <td style='text-align:right;padding:6px'>" . number_format((float)$meal->carbs, 1) . "g</td>
                    <td style='text-align:right;padding:6px'>" . number_format((float)$meal->fats, 1) . "g</td>
                    <td style='padding:6px;color:#64748b;font-size:10px'>" . htmlspecialchars($meal->notes ?? '') . "</td>
                </tr>";
            }

            $mealsHtml .= "
            <div style='margin-bottom:16px'>
                <div style='background:#e2e8f0;padding:6px 10px;font-weight:bold;font-size:11px;text-transform:uppercase;letter-spacing:1px'>
                    " . ($mealLabels[$mealType] ?? $mealType) . "
                </div>
                <table style='width:100%;border-collapse:collapse;font-size:11px'>
                    <thead><tr style='background:#f8fafc'>
                        <th style='padding:5px;text-align:left'>Food</th>
                        <th style='padding:5px;text-align:center'>Quantity</th>
                        <th style='padding:5px;text-align:right'>kcal</th>
                        <th style='padding:5px;text-align:right'>Protein</th>
                        <th style='padding:5px;text-align:right'>Carbs</th>
                        <th style='padding:5px;text-align:right'>Fats</th>
                        <th style='padding:5px'>Notes</th>
                    </tr></thead>
                    <tbody>{$rows}</tbody>
                </table>
            </div>";
        }

        return "
        <style>
            body { font-family: Arial, sans-serif; font-size: 12px; color: #1e293b; }
            .header { background: #1a2035; color: white; padding: 16px 20px; margin-bottom: 16px; }
        </style>

        <div class='header'>
            <table style='width:100%;border:0'>
                <tr>
                    <td style='width:60px;vertical-align:middle'>" . $this->logoHtml(48) . "</td>
                    <td style='vertical-align:middle;padding-left:12px'>
                        <div style='font-size:18px;font-weight:bold;color:white'>SJ Nutrizione</div>
                        <div style='font-size:10px;color:rgba(255,255,255,0.7)'>Sports &bull; Nutrigenomics &bull; Clinical</div>
                    </td>
                    <td style='text-align:right;vertical-align:middle;color:rgba(255,255,255,0.8);font-size:11px;font-weight:bold'>
                        DIET PLAN
                    </td>
                </tr>
            </table>
        </div>

        <table style='width:100%;margin-bottom:16px;font-size:12px'>
            <tr>
                <td><strong>Customer:</strong> " . htmlspecialchars($customer?->name ?? 'N/A') . "</td>
                <td><strong>Plan:</strong> " . htmlspecialchars($plan->title) . "</td>
                <td style='text-align:right'><strong>Date:</strong> " . ($plan->start_date ?: date('Y-m-d')) . "</td>
            </tr>
        </table>

        <table style='width:100%;margin-bottom:16px;background:#f8fafc;padding:8px;font-size:11px'>
            <tr>
                <td style='text-align:center'><strong style='font-size:16px;color:#ef4444'>" . number_format((float)$plan->total_calories, 0) . "</strong><br><small>kcal/day</small></td>
                <td style='text-align:center'><strong style='font-size:16px;color:#3b82f6'>" . number_format((float)$plan->total_protein, 1) . "g</strong><br><small>Protein</small></td>
                <td style='text-align:center'><strong style='font-size:16px;color:#f59e0b'>" . number_format((float)$plan->total_carbs, 1) . "g</strong><br><small>Carbs</small></td>
                <td style='text-align:center'><strong style='font-size:16px;color:#22c55e'>" . number_format((float)$plan->total_fats, 1) . "g</strong><br><small>Fats</small></td>
            </tr>
        </table>

        {$mealsHtml}

        " . ($plan->description ? "<p style='color:#64748b;font-size:11px;margin-top:16px'><strong>Notes:</strong> " . htmlspecialchars($plan->description) . "</p>" : '') . "

        <div style='margin-top:30px;text-align:center;color:#94a3b8;font-size:10px;border-top:1px solid #e2e8f0;padding-top:10px'>
            SJ Nutrizione &bull; Prescribed on " . date('d M Y') . "
        </div>";
    }
}
