<?php

namespace App\Controllers\Admin;

use App\Controllers\BaseController;
use App\Models\ClientModel;
use App\Models\CompanyModel;
use App\Models\InvoiceItemModel;
use App\Models\InvoiceModel;
use App\Models\ProductModel;
use App\Models\QuoteItemModel;
use App\Models\QuoteModel;
use App\Models\UserModel;
use Dompdf\Dompdf;
use Dompdf\Options;

class QuoteController extends BaseController
{
    public function index()
    {
        $model = new QuoteModel();
        $quotes = $model->forCompany($this->currentCompanyId())
            ->select('quotes.*, clients.name as client_name')
            ->join('clients', 'clients.id = quotes.client_id')
            ->orderBy('quotes.created_at', 'DESC')
            ->paginate(15);

        return view('admin/quotes/index', ['quotes' => $quotes, 'pager' => $model->pager]);
    }

    public function create()
    {
        $clients = (new ClientModel())->forCompany($this->currentCompanyId())->findAll();
        $products = (new ProductModel())->forCompany($this->currentCompanyId())->where('is_active', 1)->findAll();
        $suggestedNumber = (new QuoteModel())->generateNumber($this->currentCompanyId());

        return view('admin/quotes/form', ['quote' => null, 'items' => [], 'clients' => $clients, 'products' => $products, 'suggestedNumber' => $suggestedNumber, 'currencies' => $this->activeCurrencies()]);
    }

    public function store()
    {
        $model = new QuoteModel();
        $data = $this->quoteData();
        $data['company_id'] = $this->currentCompanyId();
        $data['created_by'] = session()->get('admin_user_id');

        $quoteId = $model->insert($data);
        $this->saveItems($quoteId);

        return redirect()->to('/admin/quotes')->with('message', lang('App.saved_successfully'));
    }

    public function edit($id)
    {
        $model = new QuoteModel();
        $quote = $model->forCompany($this->currentCompanyId())->find($id);
        if (! $quote) return redirect()->to('/admin/quotes');

        $items = (new QuoteItemModel())->where('quote_id', $id)->findAll();
        $clients = (new ClientModel())->forCompany($this->currentCompanyId())->findAll();
        $products = (new ProductModel())->forCompany($this->currentCompanyId())->where('is_active', 1)->findAll();

        $currencies = $this->activeCurrencies();
        return view('admin/quotes/form', compact('quote', 'items', 'clients', 'products', 'currencies'));
    }

    public function update($id)
    {
        (new QuoteModel())->update($id, $this->quoteData());
        (new QuoteItemModel())->where('quote_id', $id)->delete();
        $this->saveItems($id);

        return redirect()->to('/admin/quotes')->with('message', lang('App.saved_successfully'));
    }

    public function delete($id)
    {
        (new QuoteModel())->delete($id);
        return redirect()->to('/admin/quotes')->with('message', lang('App.deleted_successfully'));
    }

    public function view($id)
    {
        $data = $this->quoteDisplayData($id);
        if (! $data) return redirect()->to('/admin/quotes');

        return view('admin/quotes/view', $data);
    }

    public function downloadPdf($id)
    {
        $data = $this->quoteDisplayData($id);
        if (! $data) return redirect()->to('/admin/quotes');

        $html = view('admin/quotes/pdf', $data);

        $options = new Options();
        $options->set('isRemoteEnabled', true);
        $options->set('defaultFont', 'DejaVu Sans');

        $dompdf = new Dompdf($options);
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4', 'portrait');
        $dompdf->render();

        return $this->response
            ->setHeader('Content-Type', 'application/pdf')
            ->setHeader('Content-Disposition', 'attachment; filename="' . $data['quote']['quote_number'] . '.pdf"')
            ->setBody($dompdf->output());
    }

    /**
     * تحويل عرض السعر لفاتورة نهائية فعلية:
     * ينسخ كل بنود العرض لفاتورة جديدة، ويحدث حالة العرض إلى "محوّل"،
     * ويربط الفاتورة الناتجة بالعرض الأصلي.
     */
    public function convertToInvoice($id)
    {
        $quoteModel = new QuoteModel();
        $quote = $quoteModel->forCompany($this->currentCompanyId())->find($id);
        if (! $quote) return redirect()->to('/admin/quotes');

        if ($quote['status'] === 'converted' && $quote['converted_invoice_id']) {
            return redirect()->to('/admin/invoices/' . $quote['converted_invoice_id'] . '/edit');
        }

        $invoiceModel = new InvoiceModel();
        $invoiceId = $invoiceModel->insert([
            'company_id' => $quote['company_id'],
            'client_id' => $quote['client_id'],
            'created_by' => session()->get('admin_user_id'),
            'invoice_number' => $invoiceModel->generateNumber($quote['company_id']),
            'amount' => $quote['amount'],
            'currency' => $quote['currency'],
            'exchange_rate_at_creation' => 1,
            'issue_date' => date('Y-m-d'),
            'due_date' => date('Y-m-d', strtotime('+7 days')),
            'status' => 'draft',
            'notes' => 'محوّلة من عرض السعر رقم ' . $quote['quote_number'],
        ]);

        $quoteItems = (new QuoteItemModel())->where('quote_id', $id)->findAll();
        $invoiceItemModel = new InvoiceItemModel();
        foreach ($quoteItems as $item) {
            $invoiceItemModel->insert([
                'invoice_id' => $invoiceId,
                'product_id' => $item['product_id'],
                'description' => $item['description'],
                'amount' => $item['amount'],
            ]);
        }

        $quoteModel->update($id, ['status' => 'converted', 'converted_invoice_id' => $invoiceId]);

        $this->logActivity('convert_quote', "حوّل عرض السعر {$quote['quote_number']} لفاتورة جديدة");

        return redirect()->to('/admin/invoices/' . $invoiceId . '/edit')->with('message', 'تم تحويل العرض لفاتورة بنجاح، راجع بياناتها وأرسلها للعميل.');
    }

    private function quoteDisplayData($id): ?array
    {
        $quote = (new QuoteModel())->forCompany($this->currentCompanyId())->find($id);
        if (! $quote) return null;

        $items = (new QuoteItemModel())->where('quote_id', $id)->findAll();
        $client = (new ClientModel())->find($quote['client_id']);
        $company = (new CompanyModel())->find($quote['company_id']);
        $creator = $quote['created_by'] ? (new UserModel())->find($quote['created_by']) : null;

        return compact('quote', 'items', 'client', 'company', 'creator');
    }

    private function quoteData(): array
    {
        return [
            'client_id' => $this->request->getPost('client_id'),
            'quote_number' => $this->request->getPost('quote_number'),
            'amount' => $this->request->getPost('amount'),
            'currency' => $this->request->getPost('currency'),
            'issue_date' => $this->request->getPost('issue_date'),
            'valid_until' => $this->request->getPost('valid_until'),
            'status' => $this->request->getPost('status'),
            'notes' => $this->request->getPost('notes'),
        ];
    }

    private function saveItems($quoteId): void
    {
        $descriptions = $this->request->getPost('item_description') ?? [];
        $amounts = $this->request->getPost('item_amount') ?? [];
        $productIds = $this->request->getPost('item_product_id') ?? [];
        $itemModel = new QuoteItemModel();

        foreach ($descriptions as $i => $description) {
            if (! $description) continue;
            $itemModel->insert([
                'quote_id' => $quoteId,
                'product_id' => $productIds[$i] ?: null,
                'description' => $description,
                'amount' => $amounts[$i] ?? 0,
            ]);
        }
    }
}
