<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\FormInstance;
use App\Models\FormField;
use App\Models\FormInstanceActAttachment;
use App\Models\FormInstanceActSection;
use App\Models\FormInstanceValue;
use App\Services\FormWorkflowService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Traits\ApiResponseTrait;
use Illuminate\Support\Facades\Storage;
use Barryvdh\DomPDF\Facade\Pdf;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\FormInstanceReportExport;
use Maatwebsite\Excel\Excel as ExcelExcel;
use App\Exports\FormInstanceSingleSheetExport;

class FormInstanceController extends Controller
{
    use ApiResponseTrait;

    public function create(Request $request)
    {
        $data = $request->validate([
            'form_template_id' => 'required|exists:form_template,id',
            'client_id' => 'required|exists:client_master,id',
            'branch_id' => 'required|exists:client_branch,id',
            'period' => 'required|string',
            'due_date' => 'required|date'
        ]);

        DB::beginTransaction();

        try {
            $instance = FormInstance::create([
                'form_template_id' => $data['form_template_id'],
                'client_id' => $data['client_id'],
                'branch_id' => $data['branch_id'],
                'period' => $data['period'],
                'due_date' => $data['due_date'],
                'current_status' => 'DRAFT'
            ]);

            // preload empty values
            $fields = FormField::where('form_template_id', $data['form_template_id'])
                ->orderBy('display_order')
                ->get();

            foreach ($fields as $field) {
                FormInstanceValue::create([
                    'form_instance_id' => $instance->id,
                    'form_field_id' => $field->id,
                    'field_value' => null
                ]);
            }

            DB::commit();

            return $this->successResponse(
                'Form instance created',
                $instance
            );
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->errorResponse('Failed', $e->getMessage(), 500);
        }
    }

    public function list()
    {
        $instances = FormInstance::with([
            'template',
            'template.state_master',
            'client',
            'client_branch',
            'assignee',
        ])
            ->orderBy('due_date', 'asc')
            ->get();

        return $this->successResponse(
            'Form instances fetched successfully',
            $instances
        );
    }



    public function upload(Request $request, $id)
    {
        $request->validate([
            'form_field_id' => 'required|exists:form_fields,id',
            'file' => 'required|file|max:10240' // 10MB
        ]);

        $instance = FormInstance::with('template.fields')->findOrFail($id);

        DB::beginTransaction();

        try {
            $field = $instance->template->fields
                ->where('id', $request->form_field_id)
                ->where('field_type', 'FILE')
                ->first();

            if (!$field) {
                return $this->errorResponse(
                    'Invalid file field',
                    null,
                    400
                );
            }

            if ($field->is_workflow_param) {
                return $this->errorResponse(
                    'Workflow fields cannot accept files',
                    null,
                    422
                );
            }

            $file = $request->file('file');
            $path = $file->store(
                'form_uploads/' . $instance->id,
                'public'
            );

            FormInstanceValue::updateOrCreate(
                [
                    'form_instance_id' => $instance->id,
                    'form_field_id' => $field->id
                ],
                ['field_value' => $path]
            );

            DB::commit();

            return $this->successResponse(
                'File uploaded successfully',
                ['path' => $path]
            );
        } catch (\Exception $e) {
            DB::rollBack();
            return $this->errorResponse(
                'File upload failed',
                $e->getMessage(),
                500
            );
        }
    }

    // public function get($id)
    // {
    //     $instance = FormInstance::with([
    //         'template.fields' => fn($q) => $q->orderBy('display_order'),
    //         'values',
    //         'actSections',
    //     ])->find($id);

    //     return $instance
    //         ? $this->successResponse('Form instance fetched', $instance)
    //         : $this->errorResponse('Form instance not found', null, 404);
    // }



    public function get($id)
    {
        $instance = FormInstance::with([
            'template',
            'template.fields' => fn($q) => $q->orderBy('display_order'),
            'values.field',
            'actSections.statutoryAct',
            'actSections.statutorySection',
            'actSections.attachments',
        ])->find($id);

        if (!$instance) {
            return $this->errorResponse('Form instance not found', null, 404);
        }

        return $this->successResponse('Form instance fetched', [
            'id' => $instance->id,
            'period' => $instance->period,
            'current_status' => $instance->current_status,
            'form_template_name' => $instance->template->form_name,
            'state_name' => $instance->template->state_master?->name,
            'client_branch_name' => $instance->client_branch->branch_name,
            'client_branch_address' => $instance->client_branch->address,
            'client_branch_city' => $instance->client_branch->city_master?->name,
            'client_branch_state' => $instance->client_branch->state_master?->name,
            /* ---------------------------------
           TOP SECTION: FORM FIELDS
        ---------------------------------- */
            'fields' => $instance->template->fields->map(function ($field) use ($instance) {
                $value = $instance->values
                    ->firstWhere('form_field_id', $field->id);

                return [
                    'field_id'    => $field->id,
                    'label'       => $field->field_label,
                    'field_type'  => $field->field_type,
                    'is_required' => $field->is_required,
                    'value'       => $value?->field_value, // ✅ SAFE
                ];
            }),

            /* ---------------------------------
           BOTTOM SECTION: COMPLIANCE TABLE
        ---------------------------------- */
            'compliances' => $instance->actSections->map(function ($row) {
                return [
                    'id' => $row->id,

                    // Act level
                    'act_name' => $row->statutoryAct?->act_name,

                    // Section / Form level
                    'section_name' => $row->statutorySection?->section,
                    'form_no' => $row->statutorySection?->form,
                    'nature_of_compliance' => $row->statutorySection?->nature_of_compliance,
                    'compliance_type' => $row->statutorySection?->nature_of_compliance,

                    // Instance-specific
                    'remarks' => $row->remarks,
                    'status' => $row->status,

                    // ✅ Attachment support
                    'attachments' => $row->attachments->map(function ($att) {
                        return [
                            'id'   => $att->id,
                            'name' => $att->attachment_name,
                            'url'  => asset('storage/' . $att->attachment_path),
                        ];
                    }),

                ];
            }),
        ]);
    }




    /* -----------------------------------------
     Save draft
    ------------------------------------------ */

    public function save(Request $request, $id)
    {
        $request->validate([
            'fields' => 'required',
            'compliances' => 'array',
            'current_status' => 'required|in:DRAFT,PROGRESS,COMPLETED',
            'compliances.*.attachment' => 'array',
            'compliances.*.attachment.*' => [
                'file',
                'max:10240', // 10 MB
                'mimes:pdf,jpg,jpeg,png,csv,xlsx,xls',
            ],

        ]);

        $instance = FormInstance::with([
            'template.fields',
            'actSections'
        ])->findOrFail($id);

            $requestedStatus = $request->input('current_status');

/* =========================================
 * RULE: COMPLETED only if all compliances COMPLIED
 * ========================================= */
if ($requestedStatus === 'COMPLETED') {

    $incomingCompliances = collect($request->input('compliances', []));

    // Build map: act_section_id => incoming status (fallback to DB status)
    $statusMap = [];

    foreach ($incomingCompliances as $row) {
        if (!empty($row['id']) && !empty($row['status'])) {
            $statusMap[$row['id']] = $row['status'];
        }
    }

    $nonCompliedCount = FormInstanceActSection::where('form_instance_id', $instance->id)
        ->get()
        ->filter(function ($section) use ($statusMap) {
            $finalStatus = $statusMap[$section->id] ?? $section->status;
            return $finalStatus !== 'COMPLIED';
        })
        ->count();

    if ($nonCompliedCount > 0) {
        return $this->errorResponse(
            'Invalid status',
            'All compliances must be COMPLIED before marking the form as COMPLETED',
            422
        );
    }
}


        DB::beginTransaction();

        try {
            /* =========================================
         * 1. SAVE FORM FIELDS (TEXT / NUMBER / DATE)
         * ========================================= */
            $fields = json_decode($request->input('fields'), true);

            foreach ($fields as $field) {
                if (!isset($field['field_id'])) continue;

                $templateField = $instance->template->fields
                    ->where('id', $field['field_id'])
                    ->where('is_workflow_param', 1)
                    ->first();

                if (!$templateField) continue;

                FormInstanceValue::updateOrCreate(
                    [
                        'form_instance_id' => $instance->id,
                        'form_field_id'    => $templateField->id,
                    ],
                    [
                        'field_value' => $field['value'],
                    ]
                );
            }

            /* =========================================
         * 2. SAVE COMPLIANCE DETAILS
         * ========================================= */
            foreach ($request->input('compliances', []) as $index => $row) {

                $actSection = FormInstanceActSection::where('id', $row['id'])
                    ->where('form_instance_id', $instance->id)
                    ->first();

                if (!$actSection) continue;

                // Update text fields
                $actSection->update([
                    'status'  => $row['status'] ?? $actSection->status,
                    'remarks' => $row['remarks'] ?? null,
                ]);

                /* =========================================
             * 3. SAVE COMPLIANCE ATTACHMENT
             * ========================================= */
                if ($request->hasFile("compliances.$index.attachment")) {

                    foreach ($request->file("compliances.$index.attachment") as $file) {

                        $path = $file->store(
                            "form-instances/{$instance->id}/compliances",
                            'public'
                        );

                        FormInstanceActAttachment::create([
                            'form_instance_act_section_id' => $actSection->id,
                            'attachment_name'              => $file->getClientOriginalName(),
                            'attachment_path'              => $path,
                        ]);
                    }
                }
            }
/* =========================================
 * 4. SAVE FORM INSTANCE STATUS
 * ========================================= */
$instance->update([
    'current_status' => $requestedStatus,
]);

            DB::commit();

            return $this->successResponse('Report saved successfully');
        } catch (\Exception $e) {
            DB::rollBack();

            return $this->errorResponse(
                'Save failed',
                $e->getMessage(),
                500
            );
        }
    }

    public function deleteAttachment($id)
    {
        $attachment = FormInstanceActAttachment::findOrFail($id);

        Storage::disk('public')->delete($attachment->attachment_path);

        $attachment->delete();

        return $this->successResponse('Attachment deleted');
    }



    /* -----------------------------------------
     Workflow action
    ------------------------------------------ */
    public function action(Request $request, $id)
    {
        $request->validate([
            'action' => 'required|in:SUBMIT,APPROVE,REJECT'
        ]);

        try {
            $instance = FormInstance::findOrFail($id);

            app(FormWorkflowService::class)
                ->performAction($instance, $request->action);

            return $this->successResponse('Workflow updated');
        } catch (\Exception $e) {
            return $this->errorResponse(
                'Workflow action failed',
                $e->getMessage(),
                500
            );
        }
    }


    public function viewFile($valueId)
    {
        $value = FormInstanceValue::findOrFail($valueId);

        return response()->file(
            Storage::disk('public')->path($value->field_value)
        );
    }

    public function preview($id)
    {
        $data = $this->getFormInstanceReportData($id);
        $pdf = Pdf::loadView('reports.form-instance', $data);
        return $pdf->stream();
    }



    public function download(Request $request, $id)
    {
        $format = strtoupper($request->query('format', 'PDF'));
        $data   = $this->getFormInstanceReportData($id);

        if ($format === 'PDF') {
            return Pdf::loadView('reports.form-instance', $data)
                ->stream('compliance-report.pdf');
        }

        if ($format === 'EXCEL') {
            return Excel::download(
                new FormInstanceSingleSheetExport($data),
                'compliance-report.xlsx'
            );
        }

        if ($format === 'CSV') {
            return Excel::download(
                new FormInstanceSingleSheetExport($data),
                'compliance-report.csv',
                ExcelExcel::CSV
            );
        }

        abort(400, 'Invalid format');
    }


    private function getFormInstanceReportData($id): array
    {
        $instance = FormInstance::with([
            /* ---------------------------------
         | FORM + FIELDS (TOP SECTION)
         ---------------------------------- */
            'template',
            'template.fields' => fn($q) => $q->orderBy('display_order'),
            'values.field',

            /* ---------------------------------
         | COMPLIANCE TABLE (BOTTOM SECTION)
         ---------------------------------- */
            'actSections.statutoryAct',
            'actSections.statutorySection',
            'actSections.attachments',
        ])->findOrFail($id);

        return [
            'instance'     => $instance,
            'generated_at' => now(),
        ];
    }
}
