<?php

namespace App\Http\Controllers;

use App\Models\FeeTransaction;
use App\Models\SocUnit;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;
use Carbon\Carbon;

class FeeTransactionController extends Controller
{
    public function index()
{
    try {
        $transactions = FeeTransaction::with([
            'feeConfig' => function ($query) {
                $query->select('FC_Id', 'Fs_Id', 'SocId', 'Start_Date', 'Due_Date', 'Status', 'Per_Uni_Type', 'Frequency', 'EB_Disc', 'EB_Days', 'Blk_Payment', 'Blk_Units', 'Spl_Cate', 'Late_Charges', 'Interest_Charges', 'Int_Chg_Unit', 'IncId', 'RecId', 'created_at', 'updated_at');
            },
            'socUnit' => function ($query) {
                $query->select('SU_ID', 'SB_Id', 'UT_Id', 'Unit_No', 'created_at', 'updated_at');
            },
            'society' => function ($query) {
                $query->select('SocId', 'SocName', 'Address', 'City', 'State', 'Country', 'PinNo', 'PhoneNo', 'Email', 'created_at', 'updated_at');
            },
            'account' => function ($query) {
                $query->select('Pr_Id', 'Pr_Name'); // Removed created_at, updated_at
            }
        ])->paginate(10);

        return response()->json([
            'status' => 'success',
            'message' => 'Fee transactions retrieved successfully',
            'data' => $transactions
        ], 200);
    } catch (\Exception $e) {
        Log::error('Error retrieving fee transactions:', ['error' => $e->getMessage()]);
        return response()->json([
            'status' => 'error',
            'message' => 'An unexpected error occurred: ' . $e->getMessage()
        ], 500);
    }
}

    public function store(Request $request)
    {
        $validator = Validator::make($request->all(), [
            'Ft_Date' => 'required|date',
            'SocId' => 'required|exists:society_master,SocId',
            'Ft_VouTy' => 'required|string|in:DN',
            'Ft_VouNo' => 'required|string|max:10',
            'FC_ID' => 'required|exists:fees_config,FC_Id',
            'SU_Id' => 'required|exists:soc_units,SU_Id',
            'Dr_Amount' => 'required|numeric|min:0',
            'AccId' => 'nullable|exists:prty_masts,Pr_Id',
        ], [
            'Ft_VouTy.in' => 'Voucher type must be DN for debit records.',
            'SocId.exists' => 'The selected society does not exist.',
            'FC_ID.exists' => 'The selected fee configuration does not exist.',
            'SU_Id.exists' => 'The society unit does not exist.',
            'AccId.exists' => 'The account does not exist.',
        ]);

        if ($validator->fails()) {
            Log::error('Validation failed in store:', ['errors' => $validator->errors()->toArray()]);
            return response()->json([
                'status' => 'error',
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $data = $validator->validated();

            // Verify SU_Id belongs to SocId via unit_types
            $unitSocId = SocUnit::join('unit_types', 'soc_units.UT_Id', '=', 'unit_types.UT_Id')
                ->where('soc_units.SU_Id', $data['SU_Id'])
                ->value('unit_types.SocId');

            if ($unitSocId != $data['SocId']) {
                Log::error('Invalid SU_Id for SocId:', [
                    'SU_Id' => $data['SU_Id'],
                    'SocId' => $data['SocId']
                ]);
                return response()->json([
                    'status' => 'error',
                    'message' => 'The selected society unit does not belong to the specified society.'
                ], 422);
            }

            // Check for duplicate SU_Id for this Ft_VouNo, SocId, FC_ID
            if (FeeTransaction::where('Ft_VouNo', $data['Ft_VouNo'])
                ->where('SocId', $data['SocId'])
                ->where('FC_ID', $data['FC_ID'])
                ->where('SU_Id', $data['SU_Id'])
                ->where('Ft_VouTy', 'DN')
                ->exists()
            ) {
                Log::error('Duplicate fee transaction detected:', [
                    'Ft_VouNo' => $data['Ft_VouNo'],
                    'SocId' => $data['SocId'],
                    'FC_ID' => $data['FC_ID'],
                    'SU_Id' => $data['SU_Id']
                ]);
                return response()->json([
                    'status' => 'error',
                    'message' => 'A transaction with this voucher number, society, fee configuration, and unit already exists.'
                ], 422);
            }

            // Determine FT_Id
            $ftId = FeeTransaction::max('FT_Id') + 1;

            // Determine Ft_SrNo for debit record
            $maxSrNo = FeeTransaction::where('Ft_VouNo', $data['Ft_VouNo'])
                ->where('SocId', $data['SocId'])
                ->where('FC_ID', $data['FC_ID'])
                ->where('Ft_VouTy', 'DN')
                ->max('Ft_SrNo') ?? 0;
            $srNo = $maxSrNo + 1;

            // Create debit record
            $transactionData = [
                'FT_Id' => $ftId,
                'Ft_Date' => $data['Ft_Date'],
                'SocId' => $data['SocId'],
                'Ft_VouTy' => $data['Ft_VouTy'],
                'Ft_VouNo' => $data['Ft_VouNo'],
                'Ft_SrNo' => $srNo,
                'AccId' => isset($data['AccId']) ? $data['AccId'] : null,
                'FC_ID' => $data['FC_ID'],
                'SU_Id' => $data['SU_Id'],
                'Dr_Amount' => $data['Dr_Amount'],
                'Cr_Amount' => 0,
                'Description' => 'Debit for unit ' . $data['SU_Id'],
            ];

            $transaction = FeeTransaction::create($transactionData);
            $transaction->load(['feeConfig', 'socUnit', 'society', 'account']);

            Log::info('Created debit transaction:', [
                'FT_Id' => $ftId,
                'SU_Id' => $data['SU_Id'],
                'Ft_SrNo' => $srNo,
                'Dr_Amount' => $data['Dr_Amount'],
                'AccId' => $transactionData['AccId']
            ]);

            return response()->json([
                'status' => 'success',
                'message' => 'Fee transaction created successfully',
                'data' => $transaction
            ], 201);
        } catch (\Exception $e) {
            Log::error('Error creating fee transaction:', ['error' => $e->getMessage()]);
            return response()->json([
                'status' => 'error',
                'message' => 'An unexpected error occurred: ' . $e->getMessage()
            ], 500);
        }
    }

  public function show($id)
{
    try {
        $transaction = FeeTransaction::with([
            'feeConfig' => function ($query) {
                $query->select('FC_Id', 'Fs_Id', 'SocId', 'Start_Date', 'Due_Date', 'Status', 'Per_Uni_Type', 'Frequency', 'EB_Disc', 'EB_Days', 'Blk_Payment', 'Blk_Units', 'Spl_Cate', 'Late_Charges', 'Interest_Charges', 'Int_Chg_Unit', 'IncId', 'RecId', 'created_at', 'updated_at');
            },
            'socUnit' => function ($query) {
                $query->select('SU_ID', 'SB_Id', 'UT_Id', 'Unit_No', 'created_at', 'updated_at');
            },
            'society' => function ($query) {
                $query->select('SocId', 'SocName', 'Address', 'City', 'State', 'Country', 'PinNo', 'PhoneNo', 'Email', 'created_at', 'updated_at');
            },
            'account' => function ($query) {
                $query->select('Pr_Id', 'Pr_Name'); // Removed created_at, updated_at
            }
        ])->find($id);

        if (!$transaction) {
            return response()->json([
                'status' => 'error',
                'message' => 'Fee transaction not found'
            ], 404);
        }

        return response()->json([
            'status' => 'success',
            'message' => 'Fee transaction retrieved successfully',
            'data' => $transaction
        ], 200);
    } catch (\Exception $e) {
        Log::error('Error retrieving fee transaction:', ['error' => $e->getMessage()]);
        return response()->json([
            'status' => 'error',
            'message' => 'An unexpected error occurred: ' . $e->getMessage()
        ], 500);
    }
}
    public function update(Request $request, $id)
    {
        $transaction = FeeTransaction::find($id);

        if (!$transaction) {
            return response()->json([
                'status' => 'error',
                'message' => 'Fee transaction not found'
            ], 404);
        }

        $validator = Validator::make($request->all(), [
            'Ft_Date' => 'required|date',
            'SocId' => 'required|exists:society_master,SocId',
            'Ft_VouTy' => 'required|string|in:DN,REC',
            'Ft_VouNo' => 'required|string|max:10',
            'Ft_SrNo' => 'required|integer|min:1',
            'AccId' => 'nullable|exists:prty_masts,Pr_Id',
            'FC_ID' => 'required|exists:fees_config,FC_Id',
            'SU_Id' => 'nullable|exists:soc_units,SU_Id',
            'Chq_No' => 'nullable|string|max:255',
            'Chq_Dt' => 'nullable|date',
            'Cr_Amount' => 'nullable|numeric|min:0',
            'Dr_Amount' => 'nullable|numeric|min:0',
            'Ref_VouNo' => 'nullable|string|max:10',
            'Approved_By' => 'nullable|string|max:255',
            'Approved_Date' => 'nullable|date',
            'Description' => 'nullable|string|max:25',
        ], [
            'Ft_VouTy.in' => 'Voucher type must be DN or REC.',
            'SocId.exists' => 'The selected society does not exist.',
            'AccId.exists' => 'The selected account does not exist.',
            'FC_ID.exists' => 'The selected fee configuration does not exist.',
            'SU_Id.exists' => 'The selected society unit does not exist.',
        ]);

        if ($validator->fails()) {
            Log::error('Validation failed in update:', ['errors' => $validator->errors()->toArray()]);
            return response()->json([
                'status' => 'error',
                'message' => 'Validation failed',
                'errors' => $validator->errors()
            ], 422);
        }

        try {
            $data = $validator->validated();

            // Check for duplicate transaction (excluding current record)
            $existingTransaction = FeeTransaction::where('Ft_VouNo', $data['Ft_VouNo'])
                ->where('Ft_SrNo', $data['Ft_SrNo'])
                ->where('SocId', $data['SocId'])
                ->where('FC_ID', $data['FC_ID'])
                ->where('SU_Id', $data['SU_Id'])
                ->where('FT_Id', '!=', $id)
                ->exists();

            if ($existingTransaction) {
                Log::error('Duplicate fee transaction detected:', [
                    'Ft_VouNo' => $data['Ft_VouNo'],
                    'Ft_SrNo' => $data['Ft_SrNo'],
                    'SocId' => $data['SocId'],
                    'FC_ID' => $data['FC_ID'],
                    'SU_Id' => $data['SU_Id']
                ]);
                return response()->json([
                    'status' => 'error',
                    'message' => 'A transaction with this voucher number, serial number, society, fee configuration, and unit already exists.'
                ], 422);
            }

            $transaction->update($data);
            $transaction->load(['feeConfig', 'socUnit', 'society', 'account']);

            return response()->json([
                'status' => 'success',
                'message' => 'Fee transaction updated successfully',
                'data' => $transaction
            ], 200);
        } catch (\Exception $e) {
            Log::error('Error updating fee transaction:', ['error' => $e->getMessage()]);
            return response()->json([
                'status' => 'error',
                'message' => 'An unexpected error occurred: ' . $e->getMessage()
            ], 500);
        }
    }

    public function destroy($id)
    {
        $transaction = FeeTransaction::find($id);

        if (!$transaction) {
            return response()->json([
                'status' => 'error',
                'message' => 'Fee transaction not found'
            ], 404);
        }

        try {
            $transaction->delete();
            return response()->json([
                'status' => 'success',
                'message' => 'Fee transaction deleted successfully'
            ], 200);
        } catch (\Exception $e) {
            Log::error('Error deleting fee transaction:', ['error' => $e->getMessage()]);
            return response()->json([
                'status' => 'error',
                'message' => 'An unexpected error occurred: ' . $e->getMessage()
            ], 500);
        }
    }
}
