<?php

namespace App\Http\Controllers;

use App\Models\CharacteristicApproverMaster;
use App\Models\ClassCharacteristic;
use App\Models\RequestCharacteristic;
use Carbon\Carbon;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Storage;

class CharacteristicApprovalController extends Controller
{
    public function approve(Request $request)
    {
        return $this->updateStatus($request, 'Approved');
    }

    public function reject(Request $request)
    {
        return $this->updateStatus($request, 'Rejected');
    }

    public function holdForm(Request $request)
    {
        $id = $request->query('id');

        $level = (int) $request->query('level');

        $record = RequestCharacteristic::findOrFail($id);

        [$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
            1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
            2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
            3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
            default => abort(403, 'Invalid approver level'),
        };

        $levels = [
            1 => 'approver_status1',
            2 => 'approver_status2',
            3 => 'approver_status3',
        ];

        $currentStatus = $record->$statusColumn;

        $currentStatusColumn = $levels[$level];

        if (in_array($currentStatus, ['Approved', 'Rejected'])) {
            return view('approval.already-processed', [
                'status' => $currentStatus,
            ]);
        }

        foreach ($levels as $lvl => $column) {
            if ($lvl != $level && in_array($record->$column, ['Approved', 'Rejected'])) {
                return view('approval.already-processed', [
                    'status' => $record->$column,
                    'message' => 'Your request has already been processed by another approver',
                ]);
            }
        }

        foreach ($levels as $lvl => $column) {
            if ($record->$column == 'Hold') {

                if ($lvl == $level) {
                    return view('approval.already-processed', [
                        'status' => 'On Hold',
                    ]);
                }
                // else
                // {
                //     return view('approval.already-processed', [
                //         'status'     => 'Hold',
                //         'message'    => 'On Hold',
                //     ]);
                // }
            }
        }

        $allowedMailStatusByLevel = [
            1 => 'Sent',
            2 => 'Sent-Mail2',
            3 => 'Sent-Mail3',
        ];

        $expectedMailStatus = $allowedMailStatusByLevel[$level] ?? null;

        if ($record->mail_status != $expectedMailStatus) {
            return view('approval.approve-level', [
                'status' => 'Your approval time limit has expired.',
            ]);
        }

        return view('approval.hold-form', compact('id', 'level'));
    }

    public function rejectForm(Request $request)
    {
        $id = $request->query('id');
        $level = (int) $request->query('level');

        $record = RequestCharacteristic::findOrFail($id);

        [$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
            1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
            2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
            3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
            default => abort(403, 'Invalid approver level'),
        };

        $levels = [
            1 => 'approver_status1',
            2 => 'approver_status2',
            3 => 'approver_status3',
        ];

        $currentStatusColumn = $levels[$level];

        $currentStatus = $record->$statusColumn;

        if (in_array($currentStatus, ['Approved', 'Rejected'])) {
            return view('approval.already-processed', [
                'status' => $currentStatus,
            ]);
        }

        foreach ($levels as $lvl => $column) {
            if ($lvl != $level && in_array($record->$column, ['Approved', 'Rejected'])) {
                return view('approval.already-processed', [
                    'status' => $record->$column,
                    'message' => 'Your request has already been processed by another approver',
                ]);
            }
        }

        // foreach ($levels as $lvl => $column) {
        //     if ($record->$column == 'Hold') {

        //         if ($lvl == $level) {
        //             return view('approval.reject-form', compact('id', 'level'));
        //         }
        //         else
        //         {
        //             return view('approval.already-processed', [
        //                 'status'     => 'Hold',
        //                 'message'    => 'On Hold',
        //             ]);
        //         }
        //     }
        // }

        $allowedMailStatusByLevel = [
            1 => 'Sent',
            2 => 'Sent-Mail2',
            3 => 'Sent-Mail3',
        ];

        $expectedMailStatus = $allowedMailStatusByLevel[$level] ?? null;

        if ($record->mail_status != $expectedMailStatus) {
            return view('approval.approve-level', [
                'status' => $currentStatus,
                'message' => 'Your approval time limit has expired.',
            ]);
        }

        return view('approval.reject-form', compact('id', 'level'));
    }

    public function approveForm(Request $request)
    {
        $id = $request->query('id');
        $level = (int) $request->query('level');

        $record = RequestCharacteristic::findOrFail($id);

        [$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
            1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
            2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
            3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
            default => abort(403, 'Invalid approver level'),
        };

        $levels = [
            1 => 'approver_status1',
            2 => 'approver_status2',
            3 => 'approver_status3',
        ];

        $currentStatusColumn = $levels[$level];

        $currentStatus = $record->$statusColumn;

        if (in_array($currentStatus, ['Approved', 'Rejected'])) {
            return view('approval.already-processed', [
                'status' => $currentStatus,
            ]);
        }

        foreach ($levels as $lvl => $column) {
            if ($lvl != $level && in_array($record->$column, ['Approved', 'Rejected'])) {
                return view('approval.already-processed', [
                    'status' => $record->$column,
                    'message' => 'Your request has already been processed by another approver',
                ]);
            }
        }

        // foreach ($levels as $lvl => $column) {
        //     if ($record->$column == 'Hold') {

        //         if ($lvl == $level) {
        //             return view('approval.reject-form', compact('id', 'level'));
        //         }
        //         else
        //         {
        //             return view('approval.already-processed', [
        //                 'status'     => 'Hold',
        //                 'message'    => 'On Hold',
        //             ]);
        //         }
        //     }
        // }

        $allowedMailStatusByLevel = [
            1 => 'Sent',
            2 => 'Sent-Mail2',
            3 => 'Sent-Mail3',
        ];

        $expectedMailStatus = $allowedMailStatusByLevel[$level] ?? null;

        if ($record->mail_status != $expectedMailStatus) {
            return view('approval.approve-level', [
                'status' => $currentStatus,
                'message' => 'Your approval time limit has expired.',
            ]);
        }

        return view('approval.approve-form', compact('id', 'level'));
    }

    public function holdSave(Request $request)
    {
        $request->validate([
            'id' => 'required|integer',
            'level' => 'required|integer',
            'remark' => 'required|string',
        ]);

        return $this->updateStatus($request, 'Hold', false);
    }

    public function rejectSave(Request $request)
    {
        $request->validate([
            'id' => 'required|integer',
            'level' => 'required|integer',
            'remark' => 'required|string',
        ]);

        return $this->updateStatus($request, 'Rejected', false);
    }

    public function approveSave(Request $request)
    {
        $request->validate([
            'id' => 'required|integer',
            'level' => 'required|integer',
            'remark' => 'nullable|string',
        ]);

        return $this->updateStatus($request, 'Approved', false);
    }

    protected function updateStatus(Request $request, string $status, bool $returnView = true)
    {
        $requestId = $request->input('id');
        $level = (int) $request->input('level');

        $record = RequestCharacteristic::findOrFail($requestId);

        [$statusColumn, $approvedAtColumn, $remarkColumn] = match ($level) {
            1 => ['approver_status1', 'approved1_at', 'approver_remark1'],
            2 => ['approver_status2', 'approved2_at', 'approver_remark2'],
            3 => ['approver_status3', 'approved3_at', 'approver_remark3'],
            default => abort(403, 'Invalid approver level'),
        };

        $pendingRecords = RequestCharacteristic::where('plant_id', $record->plant_id)
            ->where('machine_id', $record->machine_id)
            ->where('aufnr', $record->aufnr)
            ->where('work_flow_id', $record->work_flow_id)
            ->whereNull('approver_status1')
            ->whereNull('approver_status2')
            ->whereNull('approver_status3')
            ->get();

        $processRecords = RequestCharacteristic::where('plant_id', $record->plant_id)
            ->where('machine_id', $record->machine_id)
            ->where('aufnr', $record->aufnr)
            ->where('work_flow_id', $record->work_flow_id)
            ->where(function ($query) {
                $query->whereNotNull('approver_status1')
                    ->orWhereNotNull('approver_status2')
                    ->orWhereNotNull('approver_status3');
            })
            ->get();

        $currentStatus = $record->$statusColumn;

        $levels = [
            1 => 'approver_status1',
            2 => 'approver_status2',
            3 => 'approver_status3',
        ];

        if (in_array($currentStatus, ['Approved', 'Rejected'])) {
            return view('approval.already-processed', [
                'status' => $currentStatus,
            ]);
        }

        foreach ($levels as $lvl => $column) {
            if ($lvl != $level && in_array($record->$column, ['Approved', 'Rejected'])) {
                return view('approval.already-processed', [
                    'status' => $record->$column,
                    'message' => 'your request has already been processed by another approver',
                ]);
            }
        }

        $allowedMailStatusByLevel = [
            1 => 'Sent',
            2 => 'Sent-Mail2',
            3 => 'Sent-Mail3',
        ];

        $expectedMailStatus = $allowedMailStatusByLevel[$level] ?? null;

        if ($record->mail_status != $expectedMailStatus) {
            if ($returnView) {
                return view('approval.approve-level', [
                    'status' => $currentStatus,
                    'message' => 'Your approval time limit has expired.',
                ]);
            }

            return response()->json([
                'status' => false,
                'message' => 'Invalid approval level for current mail status',
            ], 403);
        }

        $workflowRecords = RequestCharacteristic::where('plant_id', $record->plant_id)
            ->where('machine_id', $record->machine_id)
            ->where('aufnr', $record->aufnr)
            ->where('work_flow_id', $record->work_flow_id)
            ->get();

        $approverMasterNames = CharacteristicApproverMaster::find($record->characteristic_approver_master_id);

        if (! $approverMasterNames) {
            abort(500, 'Approver master not found');
        }

        $approverNameColumn = match ($level) {
            1 => 'name1',
            2 => 'name2',
            3 => 'name3',
            default => null,
        };

        $updatedBy = $approverNameColumn ? $approverMasterNames->$approverNameColumn : null;

        $updateData = [
            $statusColumn => $status,
            $remarkColumn => $request->input('remark'),
            $approvedAtColumn => Carbon::now(),
            'updated_by' => $updatedBy,
        ];

        if (in_array($status, ['Approved', 'Rejected'])) {
            $updateData['trigger_at'] = null;
        }

        foreach ($pendingRecords as $rec) {
            $rec->update($updateData);
        }

        foreach ($processRecords as $recd) {
            $recd->update($updateData);
        }

        foreach ($workflowRecords as $r) {
            $r->update($updateData);
        }

        // UPDATE class characteristics
        // ClassCharacteristic::where('plant_id', $record->plant_id)
        // ->where('machine_id', $record->machine_id)
        // ->where('aufnr', $record->aufnr)
        // ->update(['has_work_flow_id' => $record->work_flow_id]);

        if ($status == 'Rejected') {
            $filePath = 'uploads/LaserDocs/'.$record->work_flow_id.'.png';

            if (Storage::disk('local')->exists($filePath)) {
                Storage::disk('local')->delete($filePath);
            }
        }

        if ($returnView) {
            return match ($status) {
                'Approved' => view('approval.success'),
                'Hold' => view('approval.hold-success'),
                'Rejected' => view('approval.reject-success'),
                default => abort(500),
            };
        }

        return response()->json(['status' => true, 'message' => 'Status updated successfully']);
    }

    public function index()
    {
        //
    }

    /**
     * Store a newly created resource in storage.
     */
    public function store(Request $request)
    {
        //
    }

    /**
     * Display the specified resource.
     */
    public function show(string $id)
    {
        //
    }

    /**
     * Update the specified resource in storage.
     */
    public function update(Request $request, string $id)
    {
        //
    }

    /**
     * Remove the specified resource from storage.
     */
    public function destroy(string $id)
    {
        //
    }
}
