<?php

namespace App\Http\Controllers;

use App\Models\TaxSlab;
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Validation\ValidationException;
use Illuminate\Support\Facades\Validator;

class TaxSlabController extends Controller
{
    public function index(Request $request)
{
    try {
        $query = TaxSlab::query();

        // Search functionality - searches in multiple fields
        if ($request->has('search') && !empty($request->search)) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('Tax_Name', 'LIKE', "%{$search}%")
                  ->orWhere('Code', 'LIKE', "%{$search}%")
                  ->orWhere('TSL_Id', 'LIKE', "%{$search}%")
                  ->orWhere('From_Amt', 'LIKE', "%{$search}%")
                  ->orWhere('To_Amt', 'LIKE', "%{$search}%")
                  ->orWhere('TaxRate', 'LIKE', "%{$search}%");
            });
        }

        // Filter by Financial Year ID
        if ($request->has('fy_id') && !empty($request->fy_id)) {
            $query->where('FY_ID', $request->fy_id);
        }

        // Filter by Tax Name (Income Tax or Professional Tax)
        if ($request->has('tax_name') && !empty($request->tax_name)) {
            $query->where('Tax_Name', $request->tax_name);
        }

        // Filter by minimum From Amount
        if ($request->has('min_from_amt') && !empty($request->min_from_amt)) {
            $query->where('From_Amt', '>=', $request->min_from_amt);
        }

        // Filter by maximum To Amount
        if ($request->has('max_to_amt') && !empty($request->max_to_amt)) {
            $query->where('To_Amt', '<=', $request->max_to_amt);
        }

        // Filter by Tax Rate range
        if ($request->has('min_tax_rate') && !empty($request->min_tax_rate)) {
            $query->where('TaxRate', '>=', $request->min_tax_rate);
        }

        if ($request->has('max_tax_rate') && !empty($request->max_tax_rate)) {
            $query->where('TaxRate', '<=', $request->max_tax_rate);
        }

        // Filter by Standard Deduction
        if ($request->has('min_stand_deduc') && !empty($request->min_stand_deduc)) {
            $query->where('Stand_Deduc', '>=', $request->min_stand_deduc);
        }

        if ($request->has('max_stand_deduc') && !empty($request->max_stand_deduc)) {
            $query->where('Stand_Deduc', '<=', $request->max_stand_deduc);
        }

        // Filter by Cess
        if ($request->has('min_cess') && !empty($request->min_cess)) {
            $query->where('Cess', '>=', $request->min_cess);
        }

        if ($request->has('max_cess') && !empty($request->max_cess)) {
            $query->where('Cess', '<=', $request->max_cess);
        }

        // Sort functionality
        $sortBy = $request->get('sort_by', 'TSL_Id');
        $sortOrder = $request->get('sort_order', 'DESC');
        $query->orderBy($sortBy, $sortOrder);

        // Get per page value (default 10)
        $perPage = $request->get('per_page', 10);
        $taxSlabs = $query->paginate($perPage);

        return response()->json([
            'success' => true,
            'message' => 'Tax slabs retrieved successfully',
            'data' => $this->formatTaxSlabs($taxSlabs),
            'pagination' => [
                'total' => $taxSlabs->total(),
                'per_page' => $taxSlabs->perPage(),
                'current_page' => $taxSlabs->currentPage(),
                'last_page' => $taxSlabs->lastPage(),
                'from' => $taxSlabs->firstItem(),
                'to' => $taxSlabs->lastItem()
            ],
            'filters_applied' => [
                'search' => $request->search,
                'fy_id' => $request->fy_id,
                'tax_name' => $request->tax_name,
                'min_from_amt' => $request->min_from_amt,
                'max_to_amt' => $request->max_to_amt,
                'min_tax_rate' => $request->min_tax_rate,
                'max_tax_rate' => $request->max_tax_rate,
                'sort_by' => $sortBy,
                'sort_order' => $sortOrder
            ]
        ], 200);
    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'message' => 'Failed to retrieve tax slabs',
            'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
        ], 500);
    }
}

public function all(Request $request)
{
    try {
        $query = TaxSlab::query();

        // Search functionality
        if ($request->has('search') && !empty($request->search)) {
            $search = $request->search;
            $query->where(function($q) use ($search) {
                $q->where('Tax_Name', 'LIKE', "%{$search}%")
                  ->orWhere('Code', 'LIKE', "%{$search}%")
                  ->orWhere('From_Amt', 'LIKE', "%{$search}%")
                  ->orWhere('To_Amt', 'LIKE', "%{$search}%")
                  ->orWhere('TaxRate', 'LIKE', "%{$search}%");
            });
        }

        // Filter by Financial Year ID
        if ($request->has('fy_id') && !empty($request->fy_id)) {
            $query->where('FY_ID', $request->fy_id);
        }

        // Filter by Tax Name
        if ($request->has('tax_name') && !empty($request->tax_name)) {
            $query->where('Tax_Name', $request->tax_name);
        }

        // Filter by amount range
        if ($request->has('min_from_amt') && !empty($request->min_from_amt)) {
            $query->where('From_Amt', '>=', $request->min_from_amt);
        }

        if ($request->has('max_to_amt') && !empty($request->max_to_amt)) {
            $query->where('To_Amt', '<=', $request->max_to_amt);
        }

        // Filter by Tax Rate range
        if ($request->has('min_tax_rate') && !empty($request->min_tax_rate)) {
            $query->where('TaxRate', '>=', $request->min_tax_rate);
        }

        if ($request->has('max_tax_rate') && !empty($request->max_tax_rate)) {
            $query->where('TaxRate', '<=', $request->max_tax_rate);
        }

        // Sort functionality
        $sortBy = $request->get('sort_by', 'TSL_Id');
        $sortOrder = $request->get('sort_order', 'DESC');
        $query->orderBy($sortBy, $sortOrder);

        $taxSlabs = $query->get();

        return response()->json([
            'success' => true,
            'message' => 'All tax slabs retrieved successfully',
            'data' => $this->formatTaxSlabs($taxSlabs),
            'total_count' => count($taxSlabs),
            'filters_applied' => [
                'search' => $request->search,
                'fy_id' => $request->fy_id,
                'tax_name' => $request->tax_name,
                'min_from_amt' => $request->min_from_amt,
                'max_to_amt' => $request->max_to_amt,
                'min_tax_rate' => $request->min_tax_rate,
                'max_tax_rate' => $request->max_tax_rate,
                'sort_by' => $sortBy,
                'sort_order' => $sortOrder
            ]
        ], 200);
    } catch (\Exception $e) {
        return response()->json([
            'success' => false,
            'message' => 'Failed to retrieve tax slabs',
            'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
        ], 500);
    }
}

    public function show($id)
    {
        try {
            $taxSlab = TaxSlab::findOrFail($id);

            return response()->json([
                'success' => true,
                'message' => 'Tax slab retrieved successfully',
                'data' => $this->formatTaxSlab($taxSlab)
            ], 200);
        } catch (ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Tax slab not found with ID: ' . $id
            ], 404);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve tax slab',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    public function store(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'FY_ID' => 'required|integer|exists:fyear_master,FY_ID',
                'From_Amt' => 'required|integer|min:0',
                'To_Amt' => 'required|integer|min:0|gt:From_Amt',
                'TaxRate' => 'required|integer|min:0|max:100',
                'Tax_Name' => 'required|string|in:Income Tax,Professional Tax,I,P',
                'Code' => 'nullable|string|max:4',                    // New field validation
                'Stand_Deduc' => 'nullable|integer|min:0',           // New field validation
                'Cess' => 'nullable|numeric|min:0|max:100',          // New field validation
                'Cess_Amount' => 'nullable|integer|min:0'            // New field validation
            ], [
                'FY_ID.required' => 'Financial Year ID is required',
                'FY_ID.integer' => 'Financial Year ID must be an integer',
                'FY_ID.exists' => 'Financial Year does not exist',
                'From_Amt.required' => 'From Amount is required',
                'From_Amt.integer' => 'From Amount must be an integer',
                'From_Amt.min' => 'From Amount must be at least 0',
                'To_Amt.required' => 'To Amount is required',
                'To_Amt.integer' => 'To Amount must be an integer',
                'To_Amt.min' => 'To Amount must be at least 0',
                'To_Amt.gt' => 'To Amount must be greater than From Amount',
                'TaxRate.required' => 'Tax Rate is required',
                'TaxRate.integer' => 'Tax Rate must be an integer',
                'TaxRate.min' => 'Tax Rate must be at least 0',
                'TaxRate.max' => 'Tax Rate must not exceed 100',
                'Tax_Name.required' => 'Tax Name is required',
                'Tax_Name.in' => 'Tax Name must be either Income Tax or Professional Tax',
                'Code.max' => 'Code must not exceed 4 characters',
                'Stand_Deduc.min' => 'Standard Deduction must be at least 0',
                'Cess.min' => 'Cess must be at least 0',
                'Cess.max' => 'Cess must not exceed 100',
                'Cess_Amount.min' => 'Cess Amount must be at least 0'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation errors',
                    'errors' => $validator->errors()
                ], 422);
            }

            $taxSlab = TaxSlab::create([
                'FY_ID' => $request->FY_ID,
                'From_Amt' => $request->From_Amt,
                'To_Amt' => $request->To_Amt,
                'TaxRate' => $request->TaxRate,
                'Tax_Name' => $request->Tax_Name,
                'Code' => $request->Code,                      // New field
                'Stand_Deduc' => $request->Stand_Deduc ?? 0,   // New field
                'Cess' => $request->Cess ?? 0,                 // New field
                'Cess_Amount' => $request->Cess_Amount ?? 0    // New field
            ]);

            return response()->json([
                'success' => true,
                'message' => 'Tax slab created successfully',
                'data' => $this->formatTaxSlab($taxSlab)
            ], 201);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to create tax slab',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    public function update(Request $request, $id)
    {
        try {
            $taxSlab = TaxSlab::findOrFail($id);

            $validator = Validator::make($request->all(), [
                'FY_ID' => 'sometimes|integer|exists:fyear_master,FY_ID',
                'From_Amt' => 'sometimes|integer|min:0',
                'To_Amt' => 'sometimes|integer|min:0|gt:From_Amt',
                'TaxRate' => 'sometimes|integer|min:0|max:100',
                'Tax_Name' => 'required|string|in:Income Tax,Professional Tax,I,P',
                'Code' => 'nullable|string|max:4',                    // New field validation
                'Stand_Deduc' => 'nullable|integer|min:0',           // New field validation
                'Cess' => 'nullable|numeric|min:0|max:100',          // New field validation
                'Cess_Amount' => 'nullable|integer|min:0'            // New field validation
            ], [
                'FY_ID.integer' => 'Financial Year ID must be an integer',
                'FY_ID.exists' => 'Financial Year does not exist',
                'From_Amt.integer' => 'From Amount must be an integer',
                'From_Amt.min' => 'From Amount must be at least 0',
                'To_Amt.integer' => 'To Amount must be an integer',
                'To_Amt.min' => 'To Amount must be at least 0',
                'To_Amt.gt' => 'To Amount must be greater than From Amount',
                'TaxRate.integer' => 'Tax Rate must be an integer',
                'TaxRate.min' => 'Tax Rate must be at least 0',
                'TaxRate.max' => 'Tax Rate must not exceed 100',
                'Tax_Name.in' => 'Tax Name must be either Income Tax or Professional Tax',
                'Code.max' => 'Code must not exceed 4 characters',
                'Stand_Deduc.min' => 'Standard Deduction must be at least 0',
                'Cess.min' => 'Cess must be at least 0',
                'Cess.max' => 'Cess must not exceed 100',
                'Cess_Amount.min' => 'Cess Amount must be at least 0'
            ]);

            if ($validator->fails()) {
                return response()->json([
                    'success' => false,
                    'message' => 'Validation errors',
                    'errors' => $validator->errors()
                ], 422);
            }

            if ($request->has('FY_ID')) {
                $taxSlab->FY_ID = $request->FY_ID;
            }
            if ($request->has('From_Amt')) {
                $taxSlab->From_Amt = $request->From_Amt;
            }
            if ($request->has('To_Amt')) {
                $taxSlab->To_Amt = $request->To_Amt;
            }
            if ($request->has('TaxRate')) {
                $taxSlab->TaxRate = $request->TaxRate;
            }
            if ($request->has('Tax_Name')) {
                $taxSlab->Tax_Name = $request->Tax_Name;
            }
            if ($request->has('Code')) {                          // New field update
                $taxSlab->Code = $request->Code;
            }
            if ($request->has('Stand_Deduc')) {                   // New field update
                $taxSlab->Stand_Deduc = $request->Stand_Deduc;
            }
            if ($request->has('Cess')) {                          // New field update
                $taxSlab->Cess = $request->Cess;
            }
            if ($request->has('Cess_Amount')) {                   // New field update
                $taxSlab->Cess_Amount = $request->Cess_Amount;
            }

            $taxSlab->save();

            return response()->json([
                'success' => true,
                'message' => 'Tax slab updated successfully',
                'data' => $this->formatTaxSlab($taxSlab)
            ], 200);
        } catch (ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Tax slab not found with ID: ' . $id
            ], 404);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to update tax slab',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    public function destroy($id)
    {
        try {
            $taxSlab = TaxSlab::findOrFail($id);
            $taxSlab->delete();

            return response()->json([
                'success' => true,
                'message' => 'Tax slab deleted successfully'
            ], 200);
        } catch (ModelNotFoundException $e) {
            return response()->json([
                'success' => false,
                'message' => 'Tax slab not found with ID: ' . $id
            ], 404);
        } catch (\Exception $e) {
            return response()->json([
                'success' => false,
                'message' => 'Failed to delete tax slab',
                'error' => env('Development_Mode') == 'Prod' 
        ? 'Something went wrong. Please try again later.' 
        : $e->getMessage()
            ], 500);
        }
    }

    private function formatTaxSlabs($taxSlabs)
    {
        $formatted = [];
        foreach ($taxSlabs as $slab) {
            $formatted[] = $this->formatTaxSlab($slab);
        }
        return $formatted;
    }

    private function formatTaxSlab($slab)
    {
        return [
            'TSL_Id' => $slab->TSL_Id,
            'FY_ID' => $slab->FY_ID,
            'From_Amt' => $slab->From_Amt,
            'To_Amt' => $slab->To_Amt,
            'TaxRate' => $slab->TaxRate,
            'Tax_Name' => $slab->Tax_Name,
            'Code' => $slab->Code,                    // New field
            'Stand_Deduc' => $slab->Stand_Deduc,      // New field
            'Cess' => $slab->Cess,                    // New field
            'Cess_Amount' => $slab->Cess_Amount,      // New field
            'created_at' => $slab->created_at ? $slab->created_at->format('Y-m-d H:i:s') : null,
            'updated_at' => $slab->updated_at ? $slab->updated_at->format('Y-m-d H:i:s') : null
        ];
    }
}
