<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\TipoReunion;
use App\Support\HistorialLogger;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use OpenSpout\Common\Entity\Row;
use OpenSpout\Common\Entity\Style\Style;
use OpenSpout\Writer\XLSX\Writer as XLSXWriter;

class TipoReunionController extends Controller
{
    public function options()
    {
        return response()->json(
            TipoReunion::query()
                ->where('estado', 'activo')
                ->orderBy('nombre_tipo')
                ->get(['id_tipo_reunion', 'nombre_tipo'])
        );
    }

    public function export(Request $request)
    {
        $query = TipoReunion::query();

        if ($request->filled('estado')) {
            $query->where('estado', $request->string('estado'));
        }

        if ($request->filled('q')) {
            $q = trim((string) $request->string('q'));
            if ($q !== '') {
                $query->where('nombre_tipo', 'like', '%'.$q.'%');
            }
        }

        $fileName = 'tipos_reunion.xlsx';

        return response()->streamDownload(function () use ($query) {
            $writer = new XLSXWriter();
            $writer->openToFile('php://output');
            $writer->getCurrentSheet()->setName('Tipos de reunión');

            $headerStyle = (new Style())->setFontBold();
            $writer->addRow(Row::fromValues([
                'ID',
                'Tipo de reunión',
                'Estado',
            ], $headerStyle));

            $query->orderBy('nombre_tipo')->chunk(500, function ($rows) use ($writer) {
                foreach ($rows as $row) {
                    $writer->addRow(Row::fromValues([
                        (string) ($row->id_tipo_reunion ?? ''),
                        (string) ($row->nombre_tipo ?? ''),
                        (string) ($row->estado ?? ''),
                    ]));
                }
            });

            $writer->close();
        }, $fileName, ['Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']);
    }

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

        if ($request->filled('estado')) {
            $query->where('estado', $request->string('estado'));
        }

        if ($request->filled('q')) {
            $q = trim((string) $request->string('q'));
            if ($q !== '') {
                $query->where('nombre_tipo', 'like', '%'.$q.'%');
            }
        }

        $perPage = (int) $request->integer('per_page', 50);
        if ($perPage < 1) {
            $perPage = 1;
        }
        if ($perPage > 500) {
            $perPage = 500;
        }

        $paginator = $query->orderBy('nombre_tipo')->paginate($perPage);

        return response()->json([
            'data' => $paginator->items(),
            'meta' => [
                'current_page' => $paginator->currentPage(),
                'per_page' => $paginator->perPage(),
                'last_page' => $paginator->lastPage(),
                'total' => $paginator->total(),
            ],
        ]);
    }

    public function store(Request $request)
    {
        $data = $request->validate([
            'nombre_tipo' => ['required', 'string', 'max:100', 'unique:tipos_reunion,nombre_tipo'],
            'estado' => ['sometimes', 'nullable', 'in:activo,inactivo'],
        ]);

        $data['nombre_tipo'] = trim((string) $data['nombre_tipo']);

        $tipo = TipoReunion::create([
            'nombre_tipo' => $data['nombre_tipo'],
            'estado' => $data['estado'] ?? 'activo',
        ]);

        HistorialLogger::log(
            $request->user()?->getKey(),
            'tipo_reunion_creado',
            'tipos_reunion',
            (string) $tipo->getKey(),
            'Creación de tipo de reunión',
            null,
            $tipo->toArray()
        );

        return response()->json($tipo, 201);
    }

    public function show(TipoReunion $tipoReunion)
    {
        return response()->json($tipoReunion);
    }

    public function update(Request $request, TipoReunion $tipoReunion)
    {
        $antes = $tipoReunion->toArray();

        $data = $request->validate([
            'nombre_tipo' => [
                'sometimes',
                'required',
                'string',
                'max:100',
                'unique:tipos_reunion,nombre_tipo,'.$tipoReunion->getKey().',id_tipo_reunion',
            ],
            'estado' => ['sometimes', 'nullable', 'in:activo,inactivo'],
        ]);

        if (array_key_exists('nombre_tipo', $data)) {
            $data['nombre_tipo'] = trim((string) $data['nombre_tipo']);
        }

        $oldNombre = (string) ($tipoReunion->nombre_tipo ?? '');
        $tipoReunion->fill($data)->save();
        $newNombre = (string) ($tipoReunion->nombre_tipo ?? '');

        if ($oldNombre !== '' && $newNombre !== '' && $oldNombre !== $newNombre) {
            DB::table('reuniones')->where('tipo_reunion', $oldNombre)->update(['tipo_reunion' => $newNombre]);
        }

        HistorialLogger::log(
            $request->user()?->getKey(),
            'tipo_reunion_actualizado',
            'tipos_reunion',
            (string) $tipoReunion->getKey(),
            'Actualización de tipo de reunión',
            $antes,
            $tipoReunion->toArray()
        );

        return response()->json($tipoReunion);
    }

    public function destroy(Request $request, TipoReunion $tipoReunion)
    {
        $nombre = (string) ($tipoReunion->nombre_tipo ?? '');
        $inUse = $nombre !== '' ? DB::table('reuniones')->where('tipo_reunion', $nombre)->exists() : false;

        if ($inUse) {
            if ($tipoReunion->estado !== 'inactivo') {
                $antes = $tipoReunion->toArray();
                $tipoReunion->forceFill(['estado' => 'inactivo'])->save();
                $despues = $tipoReunion->toArray();

                HistorialLogger::log(
                    $request->user()?->getKey(),
                    'tipo_reunion_inactivado',
                    'tipos_reunion',
                    (string) $tipoReunion->getKey(),
                    'Inactivación de tipo de reunión (en uso)',
                    $antes,
                    $despues
                );
            }

            return response()->json($tipoReunion);
        }

        $antes = $tipoReunion->toArray();
        $tipoReunion->delete();

        HistorialLogger::log(
            $request->user()?->getKey(),
            'tipo_reunion_eliminado',
            'tipos_reunion',
            (string) ($antes['id_tipo_reunion'] ?? $tipoReunion->getKey()),
            'Eliminación de tipo de reunión',
            $antes,
            null
        );

        return response()->json(null, 204);
    }
}
