<?php

namespace App\Controllers;

use App\Models\AuditLogModel;
use App\Models\InspectionTemplateItemModel;
use App\Models\InspectionTemplateModel;
use App\Models\InspectionTemplateSectionModel;
use CodeIgniter\HTTP\RedirectResponse;

class InspectionTemplateController extends BaseController
{
    public function index(): string
    {
        $rows = (new InspectionTemplateModel())
            ->orderBy('CAST(SUBSTRING(code, 4) AS UNSIGNED)', 'ASC', false)
            ->findAll();
        return view('inspection_templates/index', [
            'title' => 'Plantillas de inspección',
            'templates' => $rows,
        ]);
    }

    public function create(): string
    {
        return view('inspection_templates/form', [
            'title' => 'Nueva plantilla',
            'template' => null,
        ]);
    }

    public function store(): RedirectResponse
    {
        $data = $this->payload();
        if (! $this->validateData($data, $this->rules())) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }
        $id = (new InspectionTemplateModel())->insert($data, true);
        (new AuditLogModel())->record('inspection_template', (int) $id, 'create', $data);
        return redirect()->to(site_url('inspection-templates/' . $id . '/edit'))->with('success', 'Plantilla creada. Agrega sus secciones e items.');
    }

    public function edit(int $id): string
    {
        $template = (new InspectionTemplateModel())->findWithItems($id);
        if ($template === null) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }
        return view('inspection_templates/edit', [
            'title' => 'Editar plantilla: ' . $template['code'],
            'template' => $template,
        ]);
    }

    public function update(int $id): RedirectResponse
    {
        $model = new InspectionTemplateModel();
        if ($model->find($id) === null) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }
        $data = $this->payload();
        if (! $this->validateData($data, $this->rules($id))) {
            return redirect()->back()->withInput()->with('errors', $this->validator->getErrors());
        }
        $data['revision'] = ((int) ($model->find($id)['revision'] ?? 1)) + 1;
        $model->update($id, $data);
        (new AuditLogModel())->record('inspection_template', $id, 'update', $data);
        return redirect()->to(site_url('inspection-templates/' . $id . '/edit'))->with('success', 'Plantilla actualizada (revisión ' . $data['revision'] . ').');
    }

    /**
     * Saves sections + items from a single JSON payload posted from the editor.
     */
    public function saveItems(int $id): RedirectResponse
    {
        $template = (new InspectionTemplateModel())->find($id);
        if ($template === null) {
            throw \CodeIgniter\Exceptions\PageNotFoundException::forPageNotFound();
        }

        $raw = (string) $this->request->getPost('schema');
        $schema = json_decode($raw, true);
        if (! is_array($schema)) {
            return redirect()->back()->with('error', 'Estructura inválida.');
        }

        $secModel = new InspectionTemplateSectionModel();
        $itemModel = new InspectionTemplateItemModel();

        $secModel->where('template_id', $id)->delete();
        $itemModel->where('template_id', $id)->delete();

        foreach (($schema['sections'] ?? []) as $orden => $section) {
            $secId = $secModel->insert([
                'template_id' => $id,
                'titulo' => trim((string) ($section['titulo'] ?? 'Sección ' . ($orden + 1))),
                'subtitulo' => $section['subtitulo'] ?? null,
                'orden' => (int) $orden,
            ], true);

            foreach (($section['items'] ?? []) as $iOrden => $item) {
                $itemModel->insert([
                    'template_id' => $id,
                    'section_id' => $secId,
                    'numero' => $item['numero'] ?? null,
                    'pregunta' => (string) ($item['pregunta'] ?? ''),
                    'equipo' => trim((string) ($item['equipo'] ?? '')) ?: null,
                    'frecuencia' => $this->normalizeFrequency($item['frecuencia'] ?? null),
                    'tipo_campo' => $item['tipo_campo'] ?? 'yes_no_na',
                    'opciones' => isset($item['opciones']) ? json_encode($item['opciones'], JSON_UNESCAPED_UNICODE) : null,
                    'orden' => (int) $iOrden,
                    'obligatorio' => ! empty($item['obligatorio']) ? 1 : 0,
                ]);
            }
        }

        (new InspectionTemplateModel())->update($id, [
            'revision' => ((int) $template['revision']) + 1,
        ]);

        (new AuditLogModel())->record('inspection_template', $id, 'save_items', ['sections' => count($schema['sections'] ?? [])]);

        return redirect()->to(site_url('inspection-templates/' . $id . '/edit'))->with('success', 'Items guardados.');
    }

    public function delete(int $id): RedirectResponse
    {
        (new InspectionTemplateModel())->delete($id);
        (new AuditLogModel())->record('inspection_template', $id, 'delete');
        return redirect()->to(site_url('inspection-templates'))->with('success', 'Plantilla eliminada.');
    }

    private function payload(): array
    {
        return [
            'code' => strtoupper(trim((string) $this->request->getPost('code'))),
            'name' => trim((string) $this->request->getPost('name')),
            'form_code' => trim((string) $this->request->getPost('form_code')) ?: null,
            'layout_mode' => in_array($this->request->getPost('layout_mode'), ['checklist', 'equipment_table'], true)
                ? $this->request->getPost('layout_mode') : 'checklist',
            'descripcion' => trim((string) $this->request->getPost('descripcion')) ?: null,
            'activo' => $this->request->getPost('activo') ? 1 : 0,
        ];
    }

    private function rules(?int $ignoreId = null): array
    {
        $codeRule = 'required|max_length[40]|is_unique[inspection_templates.code,id,' . ($ignoreId ?? 0) . ']';
        return [
            'code' => $codeRule,
            'name' => 'required|max_length[200]',
        ];
    }

    private function normalizeFrequency(?string $frequency): ?string
    {
        $frequency = strtoupper(trim((string) $frequency));
        if ($frequency === 'Q') {
            $frequency = 'S';
        }
        return in_array($frequency, ['M', 'S', 'A'], true) ? $frequency : null;
    }
}
