<?php

namespace App\Http\Controllers\Base;

use App\Services\Sales\QuotationService;
use App\Services\Sales\RfqService;
use App\Models\CustomerVendor;
use App\Models\ProductType;
use App\Models\RawMaterial;
use App\Models\ConversionProcess;
use Illuminate\Http\Request;
use Yajra\DataTables\Facades\DataTables;

class BaseQuotationController extends BaseController
{
    protected string $module = 'quotation';
    protected string $displayName = 'Quotation';
    protected array $listRelations = ['customer', 'rfq'];
    protected array $showRelations = ['customer', 'rfq'];

    protected QuotationService $quotationService;
    protected RfqService $rfqService;

    public function __construct(QuotationService $service, RfqService $rfqService)
    {
        parent::__construct($service);
        $this->quotationService = $service;
        $this->rfqService = $rfqService;
    }

    /**
     * Display a listing of Quotations
     */
    public function index()
    {
        return $this->roleView('quotation.index');
    }

    /**
     * Get Quotations for DataTable
     */
    public function list()
    {
        $query = $this->quotationService->getForDataTable();

        return DataTables::of($query)
            ->addIndexColumn()
            ->addColumn('customer_name_display', function ($row) {
                return $row->customer?->company_name ?? 'N/A';
            })
            ->addColumn('rfq_no_display', function ($row) {
                return $row->rfq?->rfq_no ?? 'N/A';
            })
            ->editColumn('grand_total', function ($row) {
                return number_format($row->grand_total ?? 0, 2);
            })
            ->addColumn('action', function ($row) {
                return $this->getQuotationActionButtons($row);
            })
            ->rawColumns(['action'])
            ->make(true);
    }

    /**
     * Generate action buttons for Quotation
     */
    protected function getQuotationActionButtons($row): string
    {
        $showRoute = route($this->resolveRoute('quotation.show'), $row->id);
        $editRoute = route($this->resolveRoute('quotation.edit'), $row->id);
        $printRoute = route($this->resolveRoute('quotation.print'), $row->id);

        return '
            <a href="' . $showRoute . '" class="btn btn-info btn-sm" title="View">
                <i class="fas fa-eye"></i>
            </a>
            <a href="' . $editRoute . '" class="btn btn-primary btn-sm" title="Edit">
                <i class="fas fa-edit"></i>
            </a>
            <a href="' . $printRoute . '" class="btn btn-secondary btn-sm" title="Print" target="_blank">
                <i class="fas fa-print"></i>
            </a>
            <button class="btn btn-danger btn-sm delete-btn" data-id="' . $row->id . '" title="Delete">
                <i class="fas fa-trash"></i>
            </button>
        ';
    }

    /**
     * Show the form for creating a new Quotation
     */
    public function create()
    {
        $data = $this->getCreateData();
        $data['quotation_no'] = $this->quotationService->generateQuotationNumber();
        return $this->roleView('quotation.create', $data);
    }

    /**
     * Create quotation from RFQ
     */
    public function createFromRfq(int $rfqId)
    {
        $rfq = $this->rfqService->findByIdWith($rfqId, ['customerInfo']);

        if (!$rfq) {
            return $this->redirectToRoute('rfq.index')
                ->with('error', 'RFQ not found.');
        }

        $data = $this->getCreateData();
        $data['rfq'] = $rfq;
        $data['quotation_no'] = $this->quotationService->generateQuotationNumber();

        return $this->roleView('quotation.createFromRfq', $data);
    }

    /**
     * Get additional data for create/edit forms
     */
    protected function getCreateData(): array
    {
        return [
            'customers' => CustomerVendor::where('company_role', '!=', 'Vendor')->orderBy('company_name')->get(),
            'productTypes' => ProductType::orderBy('name')->get(),
            'rawMaterials' => RawMaterial::orderBy('name')->get(),
            'conversionProcesses' => ConversionProcess::orderBy('name')->get(),
            'rfqs' => $this->rfqService->getAvailableForQuotation(),
        ];
    }

    /**
     * Store a newly created Quotation
     */
    public function store(Request $request)
    {
        $validated = $this->validateStore($request);

        try {
            $quotation = $this->quotationService->createQuotation($validated);

            return $this->redirectToRoute('quotation.index')
                ->with('success', 'Quotation created successfully.');
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->with('error', 'Failed to create Quotation: ' . $e->getMessage());
        }
    }

    /**
     * Display the specified Quotation
     */
    public function show(int $id)
    {
        $quotation = $this->quotationService->findByIdWith($id, $this->showRelations);

        if (!$quotation) {
            return $this->redirectToRoute('quotation.index')
                ->with('error', 'Quotation not found.');
        }

        return $this->roleView('quotation.show', compact('quotation'));
    }

    /**
     * Show the form for editing the specified Quotation
     */
    public function edit(int $id)
    {
        $quotation = $this->quotationService->findByIdWith($id, $this->showRelations);

        if (!$quotation) {
            return $this->redirectToRoute('quotation.index')
                ->with('error', 'Quotation not found.');
        }

        $data = $this->getCreateData();
        $data['quotation'] = $quotation;

        return $this->roleView('quotation.edit', $data);
    }

    /**
     * Update the specified Quotation
     */
    public function update(Request $request, int $id)
    {
        $validated = $this->validateUpdate($request, $id);

        try {
            $quotation = $this->quotationService->updateQuotation($id, $validated);

            return $this->redirectToRoute('quotation.index')
                ->with('success', 'Quotation updated successfully.');
        } catch (\Exception $e) {
            return back()
                ->withInput()
                ->with('error', 'Failed to update Quotation: ' . $e->getMessage());
        }
    }

    /**
     * Remove the specified Quotation
     */
    public function destroy(int $id)
    {
        try {
            $this->quotationService->delete($id);

            return $this->jsonSuccess('Quotation deleted successfully.');
        } catch (\Exception $e) {
            return $this->jsonError('Failed to delete Quotation.', 500);
        }
    }

    /**
     * Print Quotation
     */
    public function print(int $id)
    {
        $quotation = $this->quotationService->findByIdWith($id, $this->showRelations);

        if (!$quotation) {
            return $this->redirectToRoute('quotation.index')
                ->with('error', 'Quotation not found.');
        }

        return $this->roleView('quotation.print', compact('quotation'));
    }

    /**
     * Clone Quotation
     */
    public function clone(int $id)
    {
        try {
            $quotation = $this->quotationService->clone($id);

            return $this->redirectToRoute('quotation.edit', ['id' => $quotation->id])
                ->with('success', 'Quotation cloned successfully. You can now edit the new quotation.');
        } catch (\Exception $e) {
            return back()->with('error', 'Failed to clone Quotation: ' . $e->getMessage());
        }
    }

    /**
     * Get validation rules
     */
    protected function getValidationRules(): array
    {
        return [
            'quotation_no' => 'nullable|string|max:50',
            'quotation_date' => 'required|date',
            'customer_name' => 'required|exists:customer_vendors,id',
            'address' => 'nullable|string',
            'gst' => 'nullable|string|max:50',
            'phone' => 'nullable|string|max:20',
            'email' => 'nullable|email|max:100',
            'cust_ref_no' => 'nullable|string|max:100',
            'rfq_no' => 'nullable|exists:rfqs,id',
            'rfq_date' => 'nullable|date',
            'part_no' => 'nullable|string|max:100',
            'project_material_no' => 'nullable|string|max:100',
            'drawing_no' => 'nullable|string|max:100',
            'drawing_rev' => 'nullable|string|max:50',
            'quantity' => 'nullable|numeric|min:0',
            'quantity_uom' => 'nullable|string|max:50',
            'description' => 'nullable|string',
            'product_type' => 'nullable|string|max:100',
            'note' => 'nullable|string',
            'sub_total' => 'nullable|numeric|min:0',
            'discount' => 'nullable|numeric|min:0',
            'round_up' => 'nullable|numeric',
            'grand_total' => 'nullable|numeric|min:0',
            'raw_materials' => 'nullable|array',
            'conversion_costs' => 'nullable|array',
            'packing_charges' => 'nullable|array',
        ];
    }

    /**
     * Search Quotations (AJAX)
     */
    public function search(Request $request)
    {
        $term = $request->input('q', '');
        $quotations = $this->quotationService->search($term);

        return response()->json([
            'results' => $quotations->map(function ($quotation) {
                return [
                    'id' => $quotation->id,
                    'text' => $quotation->quotation_no . ' - ' . ($quotation->customer?->company_name ?? 'N/A'),
                ];
            }),
        ]);
    }
}
