<?php

namespace App\Http\Controllers;

use App\Models\Contract;
use App\Models\Party;
use App\Models\Item;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\DB;

class ContractController extends Controller
{
    /**
     * Display a listing of the resource.
     */
    public function index(Request $request)
    {
        $query = Contract::with(['party', 'item']);

        // Filters
        if ($request->filled('type')) {
            $query->where('type', $request->type);
        }

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('party_id')) {
            $query->where('party_id', $request->party_id);
        }

        if ($request->filled('search')) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('contract_no', 'like', "%{$search}%")
                  ->orWhere('title', 'like', "%{$search}%")
                  ->orWhereHas('party', function($pq) use ($search) {
                      $pq->where('name', 'like', "%{$search}%");
                  });
            });
        }

        $contracts = $query->orderBy('created_at', 'desc')->paginate(20);
        $parties = Party::orderBy('name')->get();

        // Summary
        $summary = [
            'total_contracts' => Contract::count(),
            'active_contracts' => Contract::active()->count(),
            'total_value' => Contract::active()->selectRaw('SUM(agreed_rate * agreed_quantity) as total')->value('total') ?? 0,
            'pending_value' => Contract::active()->selectRaw('SUM(agreed_rate * pending_quantity) as total')->value('total') ?? 0,
        ];

        return view('contracts.index', compact('contracts', 'parties', 'summary'));
    }

    /**
     * Show the form for creating a new resource.
     */
    public function create(Request $request)
    {
        $type = $request->get('type', 'purchase');
        $parties = Party::where('type', $type === 'purchase' ? 'supplier' : 'customer')
            ->orWhere('type', 'both')
            ->orderBy('name')
            ->get();
        $items = Item::where('is_active', true)->orderBy('name')->get();
        $contractNo = Contract::generateContractNo($type);

        return view('contracts.create', compact('parties', 'items', 'contractNo', 'type'));
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        $validated = $request->validate([
            'contract_no' => 'required|string|max:50|unique:contracts,contract_no',
            'title' => 'required|string|max:255',
            'party_id' => 'required|exists:parties,id',
            'type' => 'required|in:purchase,sale',
            'start_date' => 'required|date',
            'end_date' => 'nullable|date|after_or_equal:start_date',
            'item_id' => 'nullable|exists:items,id',
            'agreed_rate' => 'required|numeric|min:0',
            'agreed_quantity' => 'required|numeric|min:0',
            'quantity_unit' => 'required|string|max:20',
            'agent_commission_rate' => 'nullable|numeric|min:0',
            'transport_rate' => 'nullable|numeric|min:0',
            'terms' => 'nullable|string',
            'remarks' => 'nullable|string',
            'status' => 'required|in:draft,active,completed,cancelled',
        ]);

        $validated['pending_quantity'] = $validated['agreed_quantity'];
        $validated['delivered_quantity'] = 0;
        $validated['created_by'] = Auth::id();

        Contract::create($validated);

        return redirect()->route('contracts.index')
            ->with('success', 'Contract created successfully.');
    }

    /**
     * Display the specified resource.
     */
    public function show(Contract $contract)
    {
        $contract->load(['party', 'item', 'creator', 'purchases.items', 'sales.items']);
        
        // Get related transactions
        $relatedTransactions = [];
        
        if ($contract->type === 'purchase') {
            $relatedTransactions = $contract->purchases()->with('items.item')->get();
        } else {
            $relatedTransactions = $contract->sales()->with('items.item')->get();
        }

        return view('contracts.show', compact('contract', 'relatedTransactions'));
    }

    /**
     * Show the form for editing the specified resource.
     */
    public function edit(Contract $contract)
    {
        $parties = Party::orderBy('name')->get();
        $items = Item::where('is_active', true)->orderBy('name')->get();

        return view('contracts.edit', compact('contract', 'parties', 'items'));
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, Contract $contract)
    {
        $validated = $request->validate([
            'title' => 'required|string|max:255',
            'party_id' => 'required|exists:parties,id',
            'start_date' => 'required|date',
            'end_date' => 'nullable|date|after_or_equal:start_date',
            'item_id' => 'nullable|exists:items,id',
            'agreed_rate' => 'required|numeric|min:0',
            'agreed_quantity' => 'required|numeric|min:0',
            'quantity_unit' => 'required|string|max:20',
            'agent_commission_rate' => 'nullable|numeric|min:0',
            'transport_rate' => 'nullable|numeric|min:0',
            'terms' => 'nullable|string',
            'remarks' => 'nullable|string',
            'status' => 'required|in:draft,active,completed,cancelled',
        ]);

        // Recalculate pending quantity
        $validated['pending_quantity'] = max(0, $validated['agreed_quantity'] - $contract->delivered_quantity);

        $contract->update($validated);

        return redirect()->route('contracts.index')
            ->with('success', 'Contract updated successfully.');
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(Contract $contract)
    {
        // Check if contract has any deliveries
        if ($contract->delivered_quantity > 0) {
            return redirect()->route('contracts.index')
                ->with('error', 'Cannot delete contract with existing deliveries.');
        }

        $contract->delete();

        return redirect()->route('contracts.index')
            ->with('success', 'Contract deleted successfully.');
    }

    /**
     * Print contract
     */
    public function print(Contract $contract)
    {
        $contract->load(['party', 'item', 'creator']);
        return view('contracts.print', compact('contract'));
    }

    /**
     * Get contracts by party (AJAX)
     */
    public function getByParty(Request $request)
    {
        $partyId = $request->party_id;
        $type = $request->type; // purchase or sale

        $contracts = Contract::where('party_id', $partyId)
            ->where('type', $type)
            ->where('status', 'active')
            ->where('pending_quantity', '>', 0)
            ->with('item')
            ->get();

        return response()->json($contracts);
    }

    /**
     * Contract report
     */
    public function report(Request $request)
    {
        $query = Contract::with(['party', 'item']);

        if ($request->filled('type')) {
            $query->where('type', $request->type);
        }

        if ($request->filled('status')) {
            $query->where('status', $request->status);
        }

        if ($request->filled('party_id')) {
            $query->where('party_id', $request->party_id);
        }

        if ($request->filled('from_date')) {
            $query->where('start_date', '>=', $request->from_date);
        }

        if ($request->filled('to_date')) {
            $query->where('start_date', '<=', $request->to_date);
        }

        $contracts = $query->orderBy('start_date', 'desc')->get();
        $parties = Party::orderBy('name')->get();

        // Summary calculations
        $summary = [
            'total_contracts' => $contracts->count(),
            'total_value' => $contracts->sum('contract_value'),
            'delivered_value' => $contracts->sum('delivered_value'),
            'pending_value' => $contracts->sum('pending_value'),
            'purchase_contracts' => $contracts->where('type', 'purchase')->count(),
            'sale_contracts' => $contracts->where('type', 'sale')->count(),
        ];

        return view('contracts.report', compact('contracts', 'parties', 'summary'));
    }
}
