<?php

declare(strict_types=1);

namespace ImovelZapAi\Documents\Application\Services;

use App\Models\User;
use ImovelZapAi\Documents\Domain\Enums\DocumentType;
use ImovelZapAi\Documents\Infrastructure\Persistence\Eloquent\DocumentTemplateModel;

final class DefaultDocumentTemplateSeeder
{
    public function ensureForTenant(string $tenantId, ?User $actor = null): void
    {
        foreach ($this->defaultDefinitions() as $type => $definition) {
            $exists = DocumentTemplateModel::query()
                ->where('tenant_id', $tenantId)
                ->where('document_type', $type)
                ->where('is_default', true)
                ->exists();

            if ($exists) {
                continue;
            }

            DocumentTemplateModel::query()->create([
                'tenant_id' => $tenantId,
                'name' => $definition['name'],
                'document_type' => $type,
                'is_default' => true,
                'is_system' => true,
                'created_by' => $actor?->id,
                'body_html' => $definition['body_html'],
            ]);
        }
    }

    public function defaultForType(string $tenantId, DocumentType|string $type, ?User $actor = null): DocumentTemplateModel
    {
        $this->ensureForTenant($tenantId, $actor);

        $typeEnum = $type instanceof DocumentType ? $type : DocumentType::from($type);

        return DocumentTemplateModel::query()
            ->where('tenant_id', $tenantId)
            ->where('document_type', $typeEnum)
            ->where('is_default', true)
            ->firstOrFail();
    }

    /** @return array<string, array{name: string, body_html: string}> */
    private function defaultDefinitions(): array
    {
        return [
            DocumentType::ProposalSale->value => [
                'name' => 'Proposta de compra padrão',
                'body_html' => $this->proposalSaleBody(),
            ],
            DocumentType::ProposalRent->value => [
                'name' => 'Proposta de locação padrão',
                'body_html' => $this->proposalRentBody(),
            ],
            DocumentType::ListingAgreement->value => [
                'name' => 'Contrato de captação padrão',
                'body_html' => $this->listingAgreementBody(),
            ],
            DocumentType::Exclusivity->value => [
                'name' => 'Contrato de exclusividade padrão',
                'body_html' => $this->exclusivityBody(),
            ],
            DocumentType::Receipt->value => [
                'name' => 'Recibo padrão',
                'body_html' => $this->receiptBody(),
            ],
            DocumentType::VisitAuthorization->value => [
                'name' => 'Autorização de visita padrão',
                'body_html' => $this->visitAuthorizationBody(),
            ],
            DocumentType::Declaration->value => [
                'name' => 'Declaração padrão',
                'body_html' => $this->declarationBody(),
            ],
            DocumentType::Term->value => [
                'name' => 'Termo padrão',
                'body_html' => $this->termBody(),
            ],
        ];
    }

    private function proposalSaleBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Proposta de compra</h1>
  <p>Olá <strong>{{cliente.nome}}</strong>,</p>
  <p>Segue proposta de compra referente ao imóvel em <strong>{{imovel.endereco}}</strong>.</p>
  <ul>
    <li>Valor proposto: <strong>{{documento.valor}}</strong></li>
    <li>Corretor responsável: {{corretor.nome}}</li>
  </ul>
  <p>{{documento.mensagem}}</p>
  <p><em>{{empresa.nome}}</em> · {{data.hoje}}</p>
</section>
HTML;
    }

    private function proposalRentBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Proposta de locação</h1>
  <p>Olá <strong>{{cliente.nome}}</strong>,</p>
  <p>Segue proposta de locação para o imóvel em <strong>{{imovel.endereco}}</strong>.</p>
  <ul>
    <li>Valor proposto: <strong>{{documento.valor}}</strong></li>
    <li>Corretor responsável: {{corretor.nome}}</li>
  </ul>
  <p>{{documento.mensagem}}</p>
  <p><em>{{empresa.nome}}</em> · {{data.hoje}}</p>
</section>
HTML;
    }

    private function listingAgreementBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Contrato de captação</h1>
  <p>Pelo presente instrumento, <strong>{{cliente.nome}}</strong> autoriza <strong>{{empresa.nome}}</strong> a promover a comercialização do imóvel situado em <strong>{{imovel.endereco}}</strong>.</p>
  <p>Valor de referência: <strong>{{documento.valor}}</strong></p>
  <p>Corretor responsável: {{corretor.nome}}</p>
  <p>Data: {{data.hoje}}</p>
</section>
HTML;
    }

    private function exclusivityBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Contrato de exclusividade</h1>
  <p><strong>{{cliente.nome}}</strong> concede exclusividade à <strong>{{empresa.nome}}</strong> para comercialização do imóvel em <strong>{{imovel.endereco}}</strong>.</p>
  <p>Valor de referência: <strong>{{documento.valor}}</strong></p>
  <p>Corretor: {{corretor.nome}}</p>
  <p>Data: {{data.hoje}}</p>
</section>
HTML;
    }

    private function receiptBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Recibo</h1>
  <p>Recebemos de <strong>{{cliente.nome}}</strong> a quantia de <strong>{{documento.valor}}</strong>, referente a serviços imobiliários relacionados ao imóvel em <strong>{{imovel.endereco}}</strong>.</p>
  <p>{{empresa.nome}} · {{corretor.nome}}</p>
  <p>Data: {{data.hoje}}</p>
</section>
HTML;
    }

    private function visitAuthorizationBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Autorização de visita</h1>
  <p>Autorizamos <strong>{{cliente.nome}}</strong> a visitar o imóvel localizado em <strong>{{imovel.endereco}}</strong>, acompanhado por {{corretor.nome}} (<strong>{{empresa.nome}}</strong>).</p>
  <p>Data: {{data.hoje}}</p>
</section>
HTML;
    }

    private function declarationBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Declaração</h1>
  <p>Eu, <strong>{{cliente.nome}}</strong>, declaro para os devidos fins informações relacionadas ao imóvel em <strong>{{imovel.endereco}}</strong>, conforme solicitado por {{corretor.nome}} (<strong>{{empresa.nome}}</strong>).</p>
  <p>Valor informado, quando aplicável: <strong>{{documento.valor}}</strong></p>
  <p>Data: {{data.hoje}}</p>
</section>
HTML;
    }

    private function termBody(): string
    {
        return <<<'HTML'
<section>
  <h1>Termo / reserva</h1>
  <p><strong>{{cliente.nome}}</strong> e <strong>{{empresa.nome}}</strong> firmam o presente termo referente ao imóvel em <strong>{{imovel.endereco}}</strong>.</p>
  <p>Valor: <strong>{{documento.valor}}</strong></p>
  <p>Corretor: {{corretor.nome}}</p>
  <p>Data: {{data.hoje}}</p>
</section>
HTML;
    }
}
