<?php

namespace App\Http\Controllers\Admin;

use App\Core\Repositories\CustomerRepository;
use App\Core\Repositories\EstimateRepository;
use App\Core\Repositories\QuotationRepository;
use App\Core\Services\Estimate\EstimateService;
use App\Http\Controllers\Controller;
use App\Models\Estimate;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;

class EstimateController extends Controller
{
    public function __construct(
        private EstimateService $estimateService,
        private CustomerRepository $customerRepository,
        private EstimateRepository $estimateRepository,
        private QuotationRepository $quotationRepository
    ) {}

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

        $filters = [
            'status' => $request->get('status'),
            'customer_id' => $request->get('customer_id'),
            'date_from' => $request->get('date_from'),
            'date_to' => $request->get('date_to'),
        ];

        $estimates = $this->estimateRepository->getPaginated(15, $filters);
        $customers = $this->customerRepository->getAll();

        return view('admin.quotation.index', [
            'quotations' => $estimates,
            'customers' => $customers,
            'filters' => $filters,
        ]);
    }

    /**
     * Show the form for creating a new estimate
     */
    public function create(): View
    {
        $this->authorize('create', Estimate::class);

        $customers = $this->customerRepository->getAll();

        $companySettings = \App\Models\CompanySetting::getSettings();
        $localizationSettings = \App\Models\LocalizationSetting::getSettings();
        $currencies = \App\Models\Currency::where('is_active', true)->orderBy('is_default', 'desc')->get();
        $signatures = \App\Models\Signature::where('is_active', true)->orderBy('is_default', 'desc')->get();
        $quotationSettings = \App\Models\QuotationSetting::getSettings();
        $nextQuotationNumber = $this->quotationRepository->generateQuotationNumber();

        // Get default validity days
        $validityDays = $quotationSettings->validity_days ?? 30;
        $defaultExpiryDate = now()->addDays($validityDays)->format('Y-m-d');

        return view('admin.quotation.create', [
            'customers' => $customers,
            'companySettings' => $companySettings,
            'localizationSettings' => $localizationSettings,
            'currencies' => $currencies,
            'signatures' => $signatures,
            'quotationSettings' => $quotationSettings,
            'nextQuotationNumber' => $nextQuotationNumber,
            'defaultExpiryDate' => $defaultExpiryDate,
        ]);
    }

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

        $validated = $request->validate([
            'customer_id' => 'required|exists:customers,id',
            'issue_date' => 'required|date',
            'expiry_date' => 'required|date|after_or_equal:issue_date',
            'status' => 'nullable|in:draft,sent,viewed,accepted,rejected,expired',
            'currency' => 'nullable|string|size:3',
            'notes' => 'nullable|string',
            'terms' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.description' => 'required|string',
            'items.*.quantity' => 'required|numeric|min:0.01',
            'items.*.unit_price' => 'required|numeric|min:0',
            'items.*.tax_rate' => 'nullable|numeric|min:0|max:100',
        ]);

        $estimate = $this->estimateService->create($validated);

        return redirect()
            ->route('admin.estimates.show', $estimate)
            ->with('success', 'Estimate created successfully.');
    }

    /**
     * Display the specified estimate
     */
    public function show(Estimate $estimate): View
    {
        $this->authorize('view', $estimate);

        $estimate->load(['customer', 'items']);

        return view('admin.quotation.show', [
            'quotation' => $estimate,
        ]);
    }

    /**
     * Show the form for editing the estimate
     */
    public function edit(Estimate $estimate): View
    {
        $this->authorize('update', $estimate);

        $estimate->load(['customer', 'items']);
        $customers = $this->customerRepository->getAll();

        $companySettings = \App\Models\CompanySetting::getSettings();
        $localizationSettings = \App\Models\LocalizationSetting::getSettings();
        $currencies = \App\Models\Currency::where('is_active', true)->orderBy('is_default', 'desc')->get();
        $signatures = \App\Models\Signature::where('is_active', true)->orderBy('is_default', 'desc')->get();

        return view('admin.quotation.edit', [
            'quotation' => $estimate,
            'customers' => $customers,
            'companySettings' => $companySettings,
            'localizationSettings' => $localizationSettings,
            'currencies' => $currencies,
            'signatures' => $signatures,
        ]);
    }

    /**
     * Update the estimate
     */
    public function update(Request $request, Estimate $estimate): RedirectResponse
    {
        $this->authorize('update', $estimate);

        $validated = $request->validate([
            'customer_id' => 'required|exists:customers,id',
            'issue_date' => 'required|date',
            'expiry_date' => 'required|date|after_or_equal:issue_date',
            'status' => 'nullable|in:draft,sent,viewed,accepted,rejected,expired',
            'currency' => 'nullable|string|size:3',
            'notes' => 'nullable|string',
            'terms' => 'nullable|string',
            'items' => 'required|array|min:1',
            'items.*.description' => 'required|string',
            'items.*.quantity' => 'required|numeric|min:0.01',
            'items.*.unit_price' => 'required|numeric|min:0',
            'items.*.tax_rate' => 'nullable|numeric|min:0|max:100',
        ]);

        $this->estimateService->update($estimate, $validated);

        return redirect()
            ->route('admin.estimates.show', $estimate)
            ->with('success', 'Estimate updated successfully.');
    }

    /**
     * Remove the estimate
     */
    public function destroy(Estimate $estimate): RedirectResponse
    {
        $this->authorize('delete', $estimate);

        $estimate->delete();

        return redirect()
            ->route('admin.estimates.index')
            ->with('success', 'Estimate deleted successfully.');
    }

    /**
     * Convert estimate to invoice
     */
    public function convertToInvoice(Estimate $estimate): RedirectResponse
    {
        $this->authorize('convertToInvoice', $estimate);

        $invoice = $this->estimateService->convertToInvoice($estimate);

        return redirect()
            ->route('admin.invoices.show', $invoice)
            ->with('success', 'Estimate converted to invoice successfully.');
    }
}
