<?php

namespace App\Http\Controllers;


use App\Models\SubLedgerMaster;
use App\Models\LedgerMaster;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Validator;
use Illuminate\Support\Facades\Log;

class SubLedgerMasterController extends Controller
{

public function index(Request $request)
{
    try {
        $query = SubLedgerMaster::query();

        if ($request->has('ledger_id')) {
            $query->whereJsonContains('Lg_Id', (int) $request->ledger_id);
        }

        if ($request->has('status')) {
            $query->where('SL_Status', $request->boolean('status'));
        }

        if ($request->filled('search')) {
            $query->search($request->search);
        }

        $sortBy    = $request->get('sort_by', 'created_at');
        $sortOrder = $request->get('sort_order', 'desc');
        $query->orderBy($sortBy, $sortOrder);

        $perPage = $request->get('per_page', 15);
        $subLedgers = $query->paginate($perPage);

        // Collect all unique ledger IDs from paginated items
        $allLedgerIds = $subLedgers->flatMap(function ($item) {
            return is_array($item->Lg_Id) ? $item->Lg_Id : [];
        })->unique()->values();

        // Fetch FULL ledger details in bulk
        $ledgersData = [];
        if ($allLedgerIds->isNotEmpty()) {
            $ledgersData = LedgerMaster::whereIn('Lg_Id', $allLedgerIds)
                ->get([
                    'Lg_Id',
                    'Lg_Code',
                    'Lg_Name',
                    'Lg_Address',
                    'Lg_City',
                    'Lg_Pin',
                    'Lg_Phone',
                    'Lg_Email',
                    'Lg_Status',

                ])
                ->keyBy('Lg_Id')
                ->map(function ($ledger) {
                    return [
                        'Lg_Id'      => $ledger->Lg_Id,
                        'Lg_Code'    => $ledger->Lg_Code ?? null,
                        'Lg_Name'    => $ledger->Lg_Name ?? null,
                        'Lg_Address' => $ledger->Lg_Address ?? null,
                        'Lg_City'    => $ledger->Lg_City ?? null,
                        'Lg_Pin'     => $ledger->Lg_Pin ?? null,
                        'Lg_Phone'   => $ledger->Lg_Phone ?? null,
                        'Lg_Email'   => $ledger->Lg_Email ?? null,
                        'Lg_Status'  => (bool) ($ledger->Lg_Status ?? false),

                    ];
                })
                ->toArray();
        }


        $subLedgers->getCollection()->transform(function ($item) use ($ledgersData) {
            $ledgerDetails = [];
            $ledgerNames = [];

            foreach ($item->Lg_Id ?? [] as $lid) {
                if (isset($ledgersData[$lid])) {
                    $ledgerDetails[] = $ledgersData[$lid];
                    $ledgerNames[]   = $ledgersData[$lid]['Lg_Name'] ?? 'Ledger #' . $lid;
                } else {
                    $ledgerDetails[] = [
                        'Lg_Id'   => $lid,
                        'Lg_Name' => 'Ledger Not Found',
                        'Lg_Code' => null,
                        'Lg_Status' => false
                    ];
                    $ledgerNames[] = 'Ledger Not Found';
                }
            }

            return (object) [
                'SL_Id' => $item->SL_Id,
                'Lg_Id' => $item->Lg_Id ?? [],
                'ledger_names' => $ledgerNames,
                'ledgers' => $ledgerDetails,  
                'SL_Code' => $item->SL_Code,
                'SL_Name' => $item->SL_Name,
                'SL_Address' => $item->SL_Address,
                'SL_City' => $item->SL_City,
                'SL_Pin' => $item->SL_Pin,
                'SL_Phone' => $item->SL_Phone,
                'SL_Email' => $item->SL_Email,
                'SL_Cont_Pers' => $item->SL_Cont_Pers,
                'SL_Cr_Lim' => (float) $item->SL_Cr_Lim,
                'SL_Draw_Pwr' => (float) $item->SL_Draw_Pwr,
                'formatted_credit_limit' => $item->formatted_credit_limit,
                'formatted_drawing_power' => $item->formatted_drawing_power,
                'SL_Status' => (bool) $item->SL_Status,
                'status_text' => $item->status_text,
                'PAN_Number' => $item->PAN_Number,
                'PAN_Verified' => (bool) $item->PAN_Verified,
                'PAN_Verified_Date' => $item->PAN_Verified_Date?->toDateString(),
                'GSTIN' => $item->GSTIN,
                'GSTIN_Verified' => (bool) $item->GSTIN_Verified,
                'GSTIN_Verified_Date' => $item->GSTIN_Verified_Date?->toDateString(),
                'GST_Exempt_Declaration' => $item->GST_Exempt_Declaration,
                'MSME_Udyam_Registration_No' => $item->MSME_Udyam_Registration_No,
                'CIN_LLPIN' => $item->CIN_LLPIN,
                'Shop_Act_Trade_License_No' => $item->Shop_Act_Trade_License_No,
                'TAN' => $item->TAN,
                'Bank_Name' => $item->Bank_Name,
                'Branch_Name' => $item->Branch_Name,
                'Account_Holder_Name' => $item->Account_Holder_Name,
                'Account_Number' => $item->Account_Number,
                'IFSC_Code' => $item->IFSC_Code,
                'Account_Type' => $item->Account_Type,
                'created_at' => $item->created_at?->toDateTimeString(),
                'updated_at' => $item->updated_at?->toDateTimeString(),
            ];
        });

        return response()->json([
            'success' => true,
            'data' => $subLedgers,
        ]);
    } catch (\Exception $e) {
        Log::error('SubLedger index error: ' . $e->getMessage(), ['trace' => $e->getTraceAsString()]);
        return response()->json(['success' => false, 'message' => 'Server error'], 500);
    }
}

    /**
     * Store a newly created sub-ledger
     */
    public function store(Request $request)
    {
        $validator = Validator::make(
            $request->all(),
            SubLedgerMaster::createRules(),
            SubLedgerMaster::validationMessages()
        );

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

        $data = $request->all();
        $record = SubLedgerMaster::create($data);

        return response()->json([
            'success' => true,
            'data' => $record,
            'message' => 'Sub-ledger created successfully'
        ], 201);
    }

    /**
     * Display the specified sub-ledger
     */
public function show($id)
{
    $record = SubLedgerMaster::find($id);

    if (!$record) {
        return response()->json([
            'success' => false,
            'message' => 'Not found'
        ], 404);
    }

    // Lg_Id array ko ledger data me convert karna
    $ledgerIds = $record->Lg_Id ?? [];

    $ledgers = \App\Models\LedgerMaster::whereIn('Lg_Id', $ledgerIds)->get();

    return response()->json([
        'success' => true,
        'data' => $record,
        'ledger_details' => $ledgers
    ]);
}


    /**
     * Update the specified sub-ledger
     */
    public function update(Request $request, $id)
    {
        $record = SubLedgerMaster::find($id);

        if (!$record) {
            return response()->json(['success' => false, 'message' => 'Not found'], 404);
        }

        $validator = Validator::make(
            $request->all(),
            SubLedgerMaster::updateRules($id),
            SubLedgerMaster::validationMessages()
        );

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

        $data = $request->all();
        $record->update($data);

        return response()->json([
            'success' => true,
            'data' => $record->fresh(),
            'message' => 'Updated successfully'
        ]);
    }

    /**
     * Remove the specified sub-ledger (soft delete)
     */
    public function destroy($id)
    {
        $record = SubLedgerMaster::find($id);

        if (!$record) {
            return response()->json(['success' => false, 'message' => 'Not found'], 404);
        }

        $record->delete();

        return response()->json([
            'success' => true,
            'message' => 'Deleted successfully'
        ]);
    }

    // ────────────────────────────────────────────────
    // Custom Methods (all kept and fixed)
    // ────────────────────────────────────────────────

    public function deactivate($id)
    {
        try {
            $subLedger = SubLedgerMaster::find($id);

            if (!$subLedger) {
                return response()->json([
                    'success' => false,
                    'message' => 'Sub-ledger not found'
                ], 404);
            }

            $subLedger->deactivate();

            return response()->json([
                'success' => true,
                'message' => 'Sub-ledger deactivated successfully',
                'data' => $subLedger->fresh()
            ]);
        } catch (\Exception $e) {
            Log::error('Deactivate error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Failed to deactivate',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function activate($id)
    {
        try {
            $subLedger = SubLedgerMaster::find($id);

            if (!$subLedger) {
                return response()->json([
                    'success' => false,
                    'message' => 'Sub-ledger not found'
                ], 404);
            }

            $ledgerIds = $subLedger->Lg_Id ?? [];
            $hasActiveLedger = false;

            if (!empty($ledgerIds)) {
                $hasActiveLedger = LedgerMaster::whereIn('Lg_Id', $ledgerIds)
                    ->where('Lg_Status', true)
                    ->exists();
            }

            if (!$hasActiveLedger && !empty($ledgerIds)) {
                return response()->json([
                    'success' => false,
                    'message' => 'Cannot activate: No active parent ledger found'
                ], 400);
            }

            $subLedger->activate();

            return response()->json([
                'success' => true,
                'message' => 'Sub-ledger activated successfully',
                'data' => $subLedger->fresh()
            ]);
        } catch (\Exception $e) {
            Log::error('Activate error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Failed to activate',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function getByLedger($ledgerId)
    {
        try {
            $ledger = LedgerMaster::find($ledgerId);

            if (!$ledger) {
                return response()->json([
                    'success' => false,
                    'message' => 'Ledger not found'
                ], 404);
            }

            $subLedgers = SubLedgerMaster::whereJsonContains('Lg_Id', (int) $ledgerId)
                ->active()
                ->orderBy('SL_Code')
                ->get();

            return response()->json([
                'success' => true,
                'data' => [
                    'ledger' => [
                        'Lg_Id'   => $ledger->Lg_Id,
                        'Lg_Code' => $ledger->Lg_Code ?? null,
                        'Lg_Name' => $ledger->Lg_Name ?? null,
                    ],
                    'sub_ledgers' => $subLedgers
                ],
                'message' => 'Sub-ledgers retrieved successfully'
            ]);
        } catch (\Exception $e) {
            Log::error('getByLedger error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Failed to retrieve sub-ledgers',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function bulkStore(Request $request)
    {
        try {
            $validator = Validator::make($request->all(), [
                'sub_ledgers' => 'required|array|min:1',
                'sub_ledgers.*.Lg_Id' => 'required|array|min:1',
                'sub_ledgers.*.Lg_Id.*' => 'exists:ledger_master,Lg_Id',
                'sub_ledgers.*.SL_Code' => 'nullable|string|max:50',
                'sub_ledgers.*.SL_Name' => 'required|string|max:150',
                'sub_ledgers.*.SL_Address' => 'nullable|string',
                'sub_ledgers.*.SL_City' => 'nullable|string|max:50',
                'sub_ledgers.*.SL_Pin' => 'nullable|string|max:20',
                'sub_ledgers.*.SL_Phone' => 'nullable|string|max:15',
                'sub_ledgers.*.SL_Email' => 'nullable|email|max:50',
                'sub_ledgers.*.SL_Cont_Pers' => 'nullable|string|max:50',
                'sub_ledgers.*.SL_Cr_Lim' => 'nullable|numeric|min:0',
                'sub_ledgers.*.SL_Draw_Pwr' => 'nullable|numeric|min:0',
                'sub_ledgers.*.SL_Status' => 'nullable|boolean',
            ], SubLedgerMaster::validationMessages());

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

            $created = [];
            $errors = [];

            foreach ($request->input('sub_ledgers', []) as $index => $data) {
                try {
                    // Check duplicate SL_Code
                    if (!empty($data['SL_Code']) && SubLedgerMaster::where('SL_Code', $data['SL_Code'])->exists()) {
                        $errors[] = ['index' => $index, 'message' => 'SL_Code already exists'];
                        continue;
                    }

                    // Check at least one active ledger
                    $ledgerIds = $data['Lg_Id'] ?? [];
                    if (!empty($ledgerIds)) {
                        $activeCount = LedgerMaster::whereIn('Lg_Id', $ledgerIds)
                            ->where('Lg_Status', true)
                            ->count();

                        if ($activeCount === 0) {
                            $errors[] = ['index' => $index, 'message' => 'No active ledger found'];
                            continue;
                        }
                    }

                    $subLedger = SubLedgerMaster::create($data);
                    $created[] = $subLedger;
                } catch (\Exception $e) {
                    $errors[] = [
                        'index' => $index,
                        'message' => $e->getMessage()
                    ];
                }
            }

            $statusCode = count($created) > 0 ? 201 : 422;

            return response()->json([
                'success' => count($created) > 0,
                'created_count' => count($created),
                'failed_count' => count($errors),
                'created' => $created,
                'errors' => $errors,
            ], $statusCode);
        } catch (\Exception $e) {
            Log::error('Bulk store error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Bulk creation failed',
                'error' => $e->getMessage()
            ], 500);
        }
    }

    public function getStatistics(Request $request)
    {
        try {
            $ledgerId = $request->query('ledger_id');

            $query = SubLedgerMaster::query();

            if ($ledgerId) {
                $query->whereJsonContains('Lg_Id', (int) $ledgerId);
            }

            $stats = $query->selectRaw('
                COUNT(*) as total_count,
                SUM(CASE WHEN SL_Status = 1 THEN 1 ELSE 0 END) as active_count,
                SUM(CASE WHEN SL_Status = 0 THEN 1 ELSE 0 END) as inactive_count,
                COALESCE(SUM(SL_Cr_Lim), 0) as total_credit_limit,
                COALESCE(SUM(SL_Draw_Pwr), 0) as total_drawing_power,
                COALESCE(AVG(SL_Cr_Lim), 0) as avg_credit_limit
            ')->first();

            return response()->json([
                'success' => true,
                'data' => $stats,
                'message' => 'Statistics retrieved successfully'
            ]);
        } catch (\Exception $e) {
            Log::error('Statistics error: ' . $e->getMessage());
            return response()->json([
                'success' => false,
                'message' => 'Failed to fetch statistics',
                'error' => $e->getMessage()
            ], 500);
        }
    }
}
