<?php

namespace App\Http\Controllers\API;

use App\Http\Controllers\Controller;
use App\Models\OBF;
use App\Models\Product;
use Illuminate\Http\Request;
use Validator, DB;

class ObfArrovalController extends Controller
{
    /** construct */
    public function __construct()
    {
        $this->middleware('permission:obf_approval-create', ['only' => ['create']]);
        $this->middleware('permission:obf_approval-edit', ['only' => ['edit']]);
        $this->middleware('permission:obf_approval-view', ['only' => ['view']]);
        $this->middleware('permission:obf_approval-delete', ['only' => ['delete']]);
    }
    /** construct */
    /** index */
    public function index(Request $request)
    {
        if (auth()->user()->can('obf_approval-view')) {
            $data = OBF::select(
                'obf.id',
                'obf.temporary_id',
                'obf.customer_name',
                'obf.booking_date',
                'obf.status',
                'obf.approval_status',
                'products.name as product_name',
                'products.veriant'
            )
                ->leftJoin('products', 'obf.product_id', '=', 'products.id')
                ->whereIn('obf.status', ['pending', 'account_accepted', 'deal_generated', 'completed'])
                ->whereIn('obf.approval_status', [
                    'pending',
                    'obf_tl_accepted',
                    'obf_sm_accepted',
                    'obf_gm_accepted',
                    'obf_accountant_accepted',
                    'obf_tl_rejected',
                    'obf_sm_rejected',
                    'obf_gm_rejected',
                    'obf_accountant_rejected'
                ]);

            if (!empty(auth()->user()->branch)) {
                $data = $data->whereRaw('FIND_IN_SET(obf.branch_id ,"' . auth()->user()->branch . '")');
            }

            $roleHierarchy = [
                'Team leader' => ['obf_tl_accepted', 'obf_sm_accepted', 'obf_gm_accepted'],
                'Sales Manager' => ['obf_sm_accepted', 'obf_gm_accepted'],
                'General Manager - Sales' => ['obf_gm_accepted'],
            ];

            $currentUser = auth()->user();
            foreach ($roleHierarchy as $role => $statuses) {
                if ($currentUser->hasRole($role)) {
                    $data = $data->whereNotIn('obf.approval_status', $statuses);
                    break;
                }
            }

            $data = $data->orderBy('obf.id', 'desc')->get();

            if (sizeof($data)) {
                return response()->json(['status' => 200, 'message' => 'Data Found.', 'Data' => $data]);
            } else {
                return response()->json(['status' => 404, 'message' => 'No Data Found.']);
            }
        } else {
            return response()->json(['status' => 401, 'message' => 'Not Authorized.']);
        }
    }
    /** index */

    public function new_index(Request $request)
    {
        if (auth()->user()->can('obf_approval-view')) {

            $discountExpr = '(COALESCE(obf_finance.finance_discount,0)+COALESCE(obf.way_off,0)+COALESCE(obf.tl_discount,0)+COALESCE(obf.sm_discount,0)+COALESCE(obf.gm_discount,0)+COALESCE(obf.bh_discount,0)+COALESCE(obf.ceo_discount,0)+COALESCE(obf.md_discount,0)+COALESCE(obf.foc_accessories,0)+COALESCE(obf.offer_ib_amount,0)+COALESCE(obf.offer_kin_amount,0))';
            $receivedExpr = '(COALESCE(receipts.booking_total,0) + COALESCE(receipts.dp_total,0) + COALESCE(receipts.disbursement_total,0) + COALESCE(exchange.total_exchange_amount,0))';

            $finance_process_status = $request->finance_process_status;
            $sales_progress_status = $request->sales_progress_status;

            $data = OBF::select(
                'obf.id',
                'obf.booking_date',
                'branches.name as branch_name',
                'obf.customer_name',
                'obf.gst',
                'Team_master.team_name',
                DB::raw("CONCAT(users.first_name,' ',users.last_name) AS sales_person_name"),
                'car_model.name AS model_name',
                'car_varient.name AS car_varient_name',
                'exteriorcolor.name as exterior_color',
                'inventory_allocated.vin_number as vin_number',
                'obf.on_road_price',
                DB::raw('COALESCE(receipts.booking_total,0) as booking_amount'),
                DB::raw('COALESCE(receipts.dp_total,0) as dp_amount'),
                'obf_finance.loan_amount as finance_amount',
                DB::raw('COALESCE(receipts.disbursement_total,0) as net_disbusment_amount'),
                DB::raw('COALESCE(exchange.total_exchange_amount,0) as exchange_amount'),
                DB::raw($receivedExpr . ' as total_received_amount'),
                DB::raw($discountExpr . ' AS total_finance_discount'),
                DB::raw("( obf.on_road_price - (COALESCE(obf_finance.finance_discount,0)+COALESCE(obf.way_off,0)+COALESCE(obf.tl_discount, 0)+COALESCE(obf.sm_discount, 0)+COALESCE(obf.gm_discount, 0)+COALESCE(obf.bh_discount, 0)+COALESCE(obf.ceo_discount, 0)+COALESCE(obf.md_discount, 0)+COALESCE(obf.foc_accessories,0)+COALESCE(obf.offer_ib_amount,0)+COALESCE(obf.offer_kin_amount,0))) as net_total"),
                DB::raw('(obf.on_road_price - (' . $receivedExpr . ' + ' . $discountExpr . ')) as due_amount'),
                'obf.status',
                'orders.status as finance_process_status',
                'obf.approval_status as sales_progress_status',
                'latest_receipt.status as receipt_status',
            )
                ->leftjoin('products', 'obf.product_id', 'products.id')
                ->leftjoin('car_model', 'car_model.id', 'products.car_model')
                ->leftjoin('users', 'users.id', '=', 'obf.sales_person_id')
                ->leftjoin('car_varient', 'car_varient.id', 'products.veriant')
                ->leftjoin('orders', 'orders.obf_id', '=', 'obf.id')
                ->leftjoin('branches', 'branches.id', '=', 'obf.branch_id')
                ->leftJoin('exteriorcolor', 'exteriorcolor.id', '=', 'products.exterior_color')
                ->leftJoin('inventory as inventory_allocated', function ($join) {
                    $join->on('inventory_allocated.id', '=', 'obf.inventory_id')
                        ->where('inventory_allocated.status', '=', 'allocated');
                })
                ->leftJoin('obf_finance', 'obf_finance.obf_id', '=', 'obf.id')
                ->leftjoin('Team_master', 'Team_master.id', 'users.team_name')
                ->leftJoin(DB::raw('(SELECT obf_id,
                    SUM(CASE WHEN receipt_type="booking_receipt" AND status!="rejected" THEN amount ELSE 0 END) as booking_total,
                    SUM(CASE WHEN receipt_type="downpayment_receipt" AND status!="rejected" THEN amount ELSE 0 END) as dp_total,
                    SUM(CASE WHEN receipt_type="disbusment_receipt" AND status!="rejected" THEN amount ELSE 0 END) as disbursement_total,
                    SUM(CASE WHEN receipt_type="access_sort_receipt" AND status!="rejected" THEN amount ELSE 0 END) as access_total
                    FROM cash_receipt
                    GROUP BY obf_id) as receipts'), 'receipts.obf_id', '=', 'obf.id')
                ->leftJoin(DB::raw('(SELECT obf_id, MAX(id) as latest_receipt_id
                    FROM cash_receipt
                    GROUP BY obf_id) as latest_receipt_ref'), 'latest_receipt_ref.obf_id', '=', 'obf.id')
                ->leftJoin('cash_receipt as latest_receipt', 'latest_receipt.id', '=', 'latest_receipt_ref.latest_receipt_id')
                ->leftJoin(DB::raw('(SELECT obf_id, SUM(total_exchange_amount) as total_exchange_amount
                    FROM exchange_purchase
                    WHERE status IN ("active", "sell")
                    GROUP BY obf_id) as exchange'), 'exchange.obf_id', '=', 'obf.id')
                ->whereIn('obf.status', ['pending', 'account_accepted', 'deal_generated', 'completed'])
                ->whereIn('obf.approval_status', ['pending', 'obf_tl_accepted', 'obf_sm_accepted', 'obf_gm_accepted', 'obf_accountant_accepted', 'obf_tl_rejected', 'obf_sm_rejected', 'obf_gm_rejected', 'obf_accountant_rejected']);

            if (!empty(auth()->user()->branch)) {
                $branchIds = array_filter(array_map('intval', explode(',', auth()->user()->branch)));
                if (!empty($branchIds)) {
                    $data = $data->whereIn('obf.branch_id', $branchIds);
                }
            }

            if (!empty($finance_process_status)) {
                $data = $data->where('orders.status', 'like', '%' . $finance_process_status . '%');
            }

            if (!empty($sales_progress_status)) {
                $data = $data->where('obf.approval_status', 'like', '%' . $sales_progress_status . '%');
            }

            $roleHierarchy = [
                'Team leader' => ['obf_tl_accepted', 'obf_sm_accepted', 'obf_gm_accepted'],
                'Sales Manager' => ['obf_sm_accepted', 'obf_gm_accepted'],
                'General Manager - Sales' => ['obf_gm_accepted'],
            ];

            $currentUser = auth()->user();
            foreach ($roleHierarchy as $role => $statuses) {
                if ($currentUser->hasRole($role)) {
                    $data = $data->whereNotIn('obf.approval_status', $statuses);
                    break;
                }
            }

            $records = $data->orderBy('obf.id', 'desc')->get();

            // Status label mapping arrays
            $statusLabels = [
                'pending' => 'Pending',
                'accepted' => 'Accepted',
                'obf_accepted' => 'Obf Accepted',
                'account_accepted' => 'Account Accepted',
                'obf_rejected' => 'Obf Rejected',
                'account_rejected' => 'Account Rejected',
                'rejected' => 'Rejected',
                'deleted' => 'Deleted',
                'completed' => 'Completed',
                'cancel' => 'Cancel',
                'deal_generated' => 'Deal Generated',
                'delete' => 'Delete',
                'refund_process' => 'Refund Process',
            ];

            $approvalStatusLabels = [
                'pending' => 'Pending',
                'obf_tl_accepted' => 'Obf TL Accepted',
                'obf_tl_rejected' => 'Obf TL Rejected',
                'obf_sm_accepted' => 'Obf SM Accepted',
                'obf_sm_rejected' => 'Obf SM Rejected',
                'obf_gm_accepted' => 'Obf GM Accepted',
                'obf_gm_rejected' => 'Obf GM Rejected',
                'obf_accountant_accepted' => 'Obf Accountant Accepted',
                'obf_accountant_rejected' => 'Obf Accountant Rejected',
                'delete' => 'Delete',
            ];

            // Map status values to readable labels
            foreach ($records as $record) {
                $user = auth()->user();
                $record->assign_flag = $user->flag ?? null;

                $record->status = $statusLabels[$record->status] ?? $record->status;
                $record->approval_status = $approvalStatusLabels[$record->approval_status] ?? $record->approval_status;
                if ($record->receipt_status) {
                    $receiptStatusMap = ['booking_receipt' => 'Booking', 'downpayment_receipt' => 'DP', 'disbusment_receipt' => 'Disbursement', 'access_sort_receipt' => 'Access/Sort'];
                    $record->receipt_status = $receiptStatusMap[$record->receipt_status] ?? $record->receipt_status;
                }
            }

            if (sizeof($records)) {
                return response()->json([
                    'status' => true,
                    'message' => 'Data Found.',
                    'data' => $records,
                ]);
            } else {
                return response()->json(['status' => false, 'message' => 'No Data Found.']);
            }
        } else {
            return response()->json(['status' => false, 'message' => 'Not Authorized.']);
        }
    }

    public function obf_approval_dropdown(Request $request)
    {
        if (auth()->user()->can('obf_approval-view')) {

            // Finance and Sales progress status lists (for dropdowns)
            $financeProgressStatusList = [
                ['key' => '-- Select Status --', 'value' => ''],
                ['key' => 'Pending', 'value' => 'pending'],
                ['key' => 'Accepted', 'value' => 'accepted'],
                ['key' => 'Obf Accepted', 'value' => 'obf_accepted'],
                ['key' => 'Account Accepted', 'value' => 'account_accepted'],
                ['key' => 'Obf Rejected', 'value' => 'obf_rejected'],
                ['key' => 'Account Rejected', 'value' => 'account_rejected'],
                ['key' => 'Rejected', 'value' => 'rejected'],
                ['key' => 'Deleted', 'value' => 'deleted'],
                ['key' => 'Completed', 'value' => 'completed'],
                ['key' => 'Cancel', 'value' => 'cancel'],
                ['key' => 'Deal Generated', 'value' => 'deal_generated'],
                ['key' => 'Refund Process', 'value' => 'refund_process'],
            ];

            $salesProgressStatusList = [
                ['key' => '-- Select Status --', 'value' => ''],
                ['key' => 'Pending', 'value' => 'pending'],
                ['key' => 'Obf TL Accepted', 'value' => 'obf_tl_accepted'],
                ['key' => 'Obf TL Rejected', 'value' => 'obf_tl_rejected'],
                ['key' => 'Obf SM Accepted', 'value' => 'obf_sm_accepted'],
                ['key' => 'Obf SM Rejected', 'value' => 'obf_sm_rejected'],
                ['key' => 'Obf GM Accepted', 'value' => 'obf_gm_accepted'],
                ['key' => 'Obf GM Rejected', 'value' => 'obf_gm_rejected'],
                ['key' => 'Obf Accountant Accepted', 'value' => 'obf_accountant_accepted'],
                ['key' => 'Obf Accountant Rejected', 'value' => 'obf_accountant_rejected'],
                ['key' => 'Delete', 'value' => 'deleted'],
            ];

            return response()->json(['status' => true, 'message' => 'Dropdown lists', 'finance_progress_status' => $financeProgressStatusList, 'sales_progress_status' => $salesProgressStatusList]);
        } else {
            return response()->json(['status' => false, 'message' => 'Not Authorized.']);
        }
    }

    /** view */
    public function view(Request $request)
    {
        if (auth()->user()->can('obf_approval-view')) {
            $path = URL('/uploads/kyc') . '/';
            $data = OBF::select(
                'obf.id',
                'obf.temporary_id',
                'obf.booking_date',
                'obf.customer_name',
                'obf.customer_type',
                'obf.company_name',
                'obf.gst',
                'obf.address',
                'obf.registration',
                'obf.email',
                'obf.pan_number',
                'obf.adhar_number',
                'obf.licance_number',
                'obf.contact_number',
                'obf.dob',
                'obf.nominee_name',
                'obf.nominee_reletion',
                'obf.nominee_age',
                'obf.occupation',
                'obf.exterior_color',
                'obf.interior_color',
                'obf.ex_showroom_price',
                'obf.on_road_price',
                'obf.on_road_price_word',
                'obf.booking_amount',
                'obf.mode_of_payment',
                'obf.status',
                'obf.approval_status',
                'obf.reason',
                'branches.name AS branch_name',
                'products.name AS product_name',
                'products.veriant',
                DB::raw("CONCAT(users.first_name,' ',users.last_name) AS sales_person_name"),
                DB::raw("CASE WHEN pan_image != '' THEN CONCAT('" . $path . "', pan_image) ELSE CONCAT('" . $path . "', 'default.jpg') END as pan_image"),
                DB::raw("CASE WHEN adhar_image != '' THEN CONCAT('" . $path . "', adhar_image) ELSE CONCAT('" . $path . "', 'default.jpg') END as adhar_image"),
                DB::raw("CASE WHEN licance_image != '' THEN CONCAT('" . $path . "', licance_image) ELSE CONCAT('" . $path . "', 'default.jpg') END as licance_image")
            )
                ->leftJoin('users', 'obf.sales_person_id', '=', 'users.id')
                ->leftJoin('branches', 'obf.branch_id', '=', 'branches.id')
                ->leftJoin('products', 'obf.product_id', '=', 'products.id')
                ->where(['obf.id' => $request->id])
                ->first();

            if ($data)
                return response()->json(['status' => 200, 'message' => 'Data found', 'data' => $data]);
            else
                return response()->json(['status' => 404, 'message' => 'No data found']);
        } else {
            return response()->json(['status' => 401, 'message' => 'Not Authorized.']);
        }
    }
    /** view */

    /** change-status */
    public function change_status(Request $request)
    {
        if (auth()->user()->can('obf_approval-delete')) {
            $rules = [
                'id' => 'required',
                'status' => 'required|in:obf_tl_accepted,obf_tl_rejected,obf_sm_accepted,obf_sm_rejected,obf_gm_accepted,obf_gm_rejected,obf_accountant_accepted,obf_accountant_rejected'
            ];

            $validator = Validator::make($request->all(), $rules);

            if ($validator->fails())
                return response()->json(['status' => false, 'message' => $validator->errors()]);

            $data = OBF::where(['id' => $request->id])->first();

            if (!empty($data)) {
                $assignFlag = auth()->user()->flag ?? null;
                $requestedStatus = $request->status;
                $currentStatus = $data->approval_status ?? 'pending';

                if ($data->status === 'deal_generated' && $assignFlag !== "4") {
                    return response()->json(['status' => false, 'message' => 'Deal Generated - You Can Not Edit this OBF']);
                }

                $allowedStatuses = [];
                if ($assignFlag === "1") {
                    if (!in_array($currentStatus, ['obf_sm_accepted', 'obf_sm_rejected', 'obf_gm_accepted', 'obf_gm_rejected', 'obf_accountant_accepted', 'obf_accountant_rejected'])) {
                        $allowedStatuses = ['obf_tl_accepted', 'obf_tl_rejected'];
                    }
                } else if ($assignFlag === "2") {
                    if (!in_array($currentStatus, ['obf_gm_accepted', 'obf_gm_rejected', 'obf_accountant_accepted', 'obf_accountant_rejected'])) {
                        $allowedStatuses = ['obf_sm_accepted', 'obf_sm_rejected'];
                    }
                } else if ($assignFlag === "3") {
                    if (!in_array($currentStatus, ['obf_accountant_accepted', 'obf_accountant_rejected'])) {
                        $allowedStatuses = ['obf_gm_accepted', 'obf_gm_rejected'];
                    }
                } else if ($assignFlag === "4") {
                    $allowedStatuses = ['obf_accountant_accepted', 'obf_accountant_rejected'];
                }

                if (empty($allowedStatuses) || !in_array($requestedStatus, $allowedStatuses)) {
                    return response()->json(['status' => false, 'message' => 'This approval action is not allowed for your current role or stage.']);
                }

                if (str_contains($requestedStatus, '_rejected') && empty($request->reason)) {
                    return response()->json(['status' => false, 'message' => ['reason' => ['The reason field is required for rejection.']]]);
                }

                $update = OBF::where(['id' => $request->id])->update([
                    'approval_status' => $requestedStatus,
                    'reason' => $request->reason,
                    'updated_at' => date('Y-m-d H:i:s'),
                    'updated_by' => auth('sanctum')->user()->id
                ]);

                if ($update) {
                    return response()->json(['status' => true, 'message' => 'Record status change successfully']);
                } else {
                    return response()->json(['status' => false, 'message' => 'Failed to update status']);
                }
            } else {
                return response()->json(['status' => false, 'message' => 'Something went wrong !']);
            }
        } else {
            return response()->json(['status' => false, 'message' => 'Not Authorized.']);
        }
    }
    /** change-status */
}
