<?php

namespace App\Http\Controllers\Admin;

use App\Http\Controllers\Controller;
use App\Models\Client;
use App\Models\Contract;
use App\Models\Installation;
use Illuminate\Http\Request;
use Illuminate\Validation\Rule;

class ContractController extends Controller
{
    private array $statuses = [
        'active' => 'Ativo',
        'expired' => 'Expirado',
        'cancelled' => 'Cancelado',
    ];

    public function index()
    {
        $contracts = Contract::with(['client', 'installation'])->latest()->paginate(10);

        return view('admin.shared.index', [
            'title' => 'Contratos',
            'subtitle' => 'Planos de monitoramento, vigência e mensalidades.',
            'createRoute' => route('admin.contracts.create'),
            'createLabel' => 'Novo Contrato',
            'columns' => ['Cliente', 'Instalação', 'Mensalidade', 'Vigência', 'Estado'],
            'rows' => $contracts->map(fn (Contract $contract) => [
                'values' => [
                    $contract->client->name ?? 'Sem cliente',
                    $contract->installation->address ?? 'Sem instalação',
                    number_format((float) $contract->monthly_fee, 2, ',', '.') . ' Kz',
                    $contract->start_date->format('d/m/Y') . ' - ' . ($contract->end_date?->format('d/m/Y') ?? 'Sem fim'),
                    $this->statuses[$contract->status] ?? $contract->status,
                ],
                'editRoute' => route('admin.contracts.edit', $contract),
                'deleteRoute' => route('admin.contracts.destroy', $contract),
            ]),
            'paginator' => $contracts,
            'emptyLabel' => 'Nenhum contrato registado.',
        ]);
    }

    public function create()
    {
        return $this->form(new Contract(), route('admin.contracts.store'), 'Novo Contrato');
    }

    public function store(Request $request)
    {
        Contract::create($this->validated($request));

        return redirect()->route('admin.contracts.index')->with('success', 'Contrato cadastrado com sucesso.');
    }

    public function show(Contract $contract)
    {
        return redirect()->route('admin.contracts.edit', $contract);
    }

    public function edit(Contract $contract)
    {
        return $this->form($contract, route('admin.contracts.update', $contract), 'Editar Contrato', 'PUT');
    }

    public function update(Request $request, Contract $contract)
    {
        $contract->update($this->validated($request));

        return redirect()->route('admin.contracts.index')->with('success', 'Contrato atualizado com sucesso.');
    }

    public function destroy(Contract $contract)
    {
        $contract->delete();

        return redirect()->route('admin.contracts.index')->with('success', 'Contrato removido com sucesso.');
    }

    private function form(Contract $contract, string $action, string $title, string $method = 'POST')
    {
        return view('admin.shared.form', [
            'title' => $title,
            'subtitle' => 'Defina a vigência, instalação associada e mensalidade.',
            'backRoute' => route('admin.contracts.index'),
            'action' => $action,
            'method' => $method,
            'submitLabel' => $method === 'POST' ? 'Cadastrar Contrato' : 'Guardar Alterações',
            'fields' => [
                ['name' => 'client_id', 'label' => 'Cliente *', 'type' => 'select', 'value' => $contract->client_id, 'options' => Client::orderBy('name')->pluck('name', 'id')],
                ['name' => 'installation_id', 'label' => 'Instalação', 'type' => 'select', 'value' => $contract->installation_id, 'options' => Installation::with('client')->get()->mapWithKeys(fn ($installation) => [$installation->id => ($installation->client->name ?? 'Cliente') . ' - ' . $installation->address]), 'empty' => 'Sem instalação'],
                ['name' => 'start_date', 'label' => 'Início *', 'type' => 'date', 'value' => optional($contract->start_date)->format('Y-m-d')],
                ['name' => 'end_date', 'label' => 'Fim', 'type' => 'date', 'value' => optional($contract->end_date)->format('Y-m-d')],
                ['name' => 'monthly_fee', 'label' => 'Mensalidade *', 'type' => 'number', 'step' => '0.01', 'value' => $contract->monthly_fee],
                ['name' => 'status', 'label' => 'Estado *', 'type' => 'select', 'value' => $contract->status ?: 'active', 'options' => $this->statuses],
            ],
        ]);
    }

    private function validated(Request $request): array
    {
        return $request->validate([
            'client_id' => ['required', 'exists:clients,id'],
            'installation_id' => ['nullable', 'exists:installations,id'],
            'start_date' => ['required', 'date'],
            'end_date' => ['nullable', 'date', 'after_or_equal:start_date'],
            'monthly_fee' => ['required', 'numeric', 'min:0'],
            'status' => ['required', Rule::in(array_keys($this->statuses))],
        ]);
    }
}
