<?php

namespace App\Http\Controllers\Base;

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

class BaseSalesOrderController extends BaseController
{
    protected string $module = 'sales';
    protected string $displayName = 'Sales Order';
    protected array $listRelations = ['items', 'customer', 'routeCard'];
    protected array $showRelations = ['items', 'customer', 'quotation', 'routeCard'];

    protected SalesOrderService $salesOrderService;
    protected QuotationService $quotationService;

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

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

    /**
     * Get Sales Orders for DataTable
     */
    public function list()
    {
        $query = $this->salesOrderService->getForDataTable();

        return DataTables::of($query)
            ->addIndexColumn()
            ->addColumn('customer_name', function ($row) {
                return $row->customer?->company_name ?? 'N/A';
            })
            ->addColumn('has_route_card', function ($row) {
                return $row->routeCard ? '<span class="badge badge-success">Yes</span>' : '<span class="badge badge-secondary">No</span>';
            })
            ->editColumn('grand_total', function ($row) {
                return number_format($row->grand_total ?? 0, 2);
            })
            ->editColumn('status', function ($row) {
                $statusColors = [
                    'Pending' => 'warning',
                    'In Progress' => 'info',
                    'Completed' => 'success',
                    'Cancelled' => 'danger',
                ];
                $color = $statusColors[$row->status] ?? 'secondary';
                return '<span class="badge badge-' . $color . '">' . ($row->status ?? 'N/A') . '</span>';
            })
            ->addColumn('action', function ($row) {
                return $this->getSalesOrderActionButtons($row);
            })
            ->rawColumns(['action', 'has_route_card', 'status'])
            ->make(true);
    }

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

        $buttons = '
            <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>';

        // Add route card button if no route card exists
        if (!$row->routeCard) {
            $createRouteCardRoute = route($this->resolveRoute('routecard.createFromSalesOrder'), $row->id);
            $buttons .= '
            <a href="' . $createRouteCardRoute . '" class="btn btn-success btn-sm" title="Create Route Card">
                <i class="fas fa-route"></i>
            </a>';
        }

        $buttons .= '
            <button class="btn btn-danger btn-sm delete-btn" data-id="' . $row->id . '" title="Delete">
                <i class="fas fa-trash"></i>
            </button>
        ';

        return $buttons;
    }

    /**
     * Show the form for creating a new Sales Order
     */
    public function create()
    {
        $data = $this->getCreateData();
        $data['sales_order_no'] = $this->salesOrderService->generateSalesOrderNumber();
        return $this->roleView('sales.create', $data);
    }

    /**
     * Create sales order from quotation
     */
    public function createFromQuotation(int $quotationId)
    {
        $quotation = $this->quotationService->findByIdWith($quotationId, ['customer']);

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

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

        return $this->roleView('sales.createFromQuotation', $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(),
            'quotations' => $this->quotationService->getAvailableForSalesOrder(),
            'statuses' => ['Pending', 'In Progress', 'Completed', 'Cancelled'],
        ];
    }

    /**
     * Store a newly created Sales Order
     */
    public function store(Request $request)
    {
        $validated = $this->validateStore($request);
        $items = $request->input('items', []);

        try {
            $salesOrder = $this->salesOrderService->createWithItems($validated, $items);

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

    /**
     * Display the specified Sales Order
     */
    public function show(int $id)
    {
        $salesOrder = $this->salesOrderService->findByIdWith($id, $this->showRelations);

        if (!$salesOrder) {
            return $this->redirectToRoute('sales.index')
                ->with('error', 'Sales Order not found.');
        }

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

    /**
     * Show the form for editing the specified Sales Order
     */
    public function edit(int $id)
    {
        $salesOrder = $this->salesOrderService->findByIdWith($id, $this->showRelations);

        if (!$salesOrder) {
            return $this->redirectToRoute('sales.index')
                ->with('error', 'Sales Order not found.');
        }

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

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

    /**
     * Update the specified Sales Order
     */
    public function update(Request $request, int $id)
    {
        $validated = $this->validateUpdate($request, $id);
        $items = $request->input('items', []);

        try {
            $salesOrder = $this->salesOrderService->updateWithItems($id, $validated, $items);

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

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

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

    /**
     * Print Sales Order
     */
    public function print(int $id)
    {
        $salesOrder = $this->salesOrderService->findByIdWith($id, $this->showRelations);

        if (!$salesOrder) {
            return $this->redirectToRoute('sales.index')
                ->with('error', 'Sales Order not found.');
        }

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

    /**
     * Update status
     */
    public function updateStatus(Request $request, int $id)
    {
        $request->validate([
            'status' => 'required|in:Pending,In Progress,Completed,Cancelled',
        ]);

        try {
            $salesOrder = $this->salesOrderService->updateStatus($id, $request->status);

            return $this->jsonSuccess('Status updated successfully.');
        } catch (\Exception $e) {
            return $this->jsonError('Failed to update status.', 500);
        }
    }

    /**
     * Get validation rules
     */
    protected function getValidationRules(): array
    {
        return [
            'sales_order_no' => 'nullable|string|max:50',
            'sales_order_date' => 'required|date',
            'grn_no' => 'nullable|string|max:100',
            'customer_ref_no' => 'nullable|string|max:100',
            'company_name' => 'required|exists:customer_vendors,id',
            'company_address' => 'nullable|string',
            'company_gstn' => 'nullable|string|max:50',
            'company_phone' => 'nullable|string|max:20',
            'company_email' => 'nullable|email|max:100',
            'quotation_no' => 'nullable|string|max:100',
            'quotation_date' => 'nullable|date',
            'rfq_no' => 'nullable|string|max:100',
            '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',
            'description' => 'nullable|string',
            'bill_address' => 'nullable|string',
            'ship_address' => 'nullable|string',
            'product_type' => 'nullable|string|max:100',
            'subtotal' => 'nullable|numeric|min:0',
            'sgst_amount' => 'nullable|numeric|min:0',
            'cgst_amount' => 'nullable|numeric|min:0',
            'igst_amount' => 'nullable|numeric|min:0',
            'round_up' => 'nullable|numeric',
            'grand_total' => 'nullable|numeric|min:0',
            'status' => 'nullable|in:Pending,In Progress,Completed,Cancelled',
        ];
    }

    /**
     * Search Sales Orders (AJAX)
     */
    public function search(Request $request)
    {
        $term = $request->input('q', '');
        $salesOrders = $this->salesOrderService->search($term);

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