<?php

namespace App\Services\Documents;

use App\Models\Company;
use App\Models\GeneratedLetter;
use App\Models\LetterHeadTemplate;
use App\Models\User;

class LetterGeneratorService
{
    /**
     * @return list<string>
     */
    public function supportedTypes(): array
    {
        return [
            GeneratedLetter::TYPE_RELIEVING,
            GeneratedLetter::TYPE_EXPERIENCE,
            GeneratedLetter::TYPE_WARNING,
            GeneratedLetter::TYPE_OFFER,
        ];
    }

    /**
     * @return array<string, string>
     */
    /**
     * @param  array<string, string>  $overrides  Placeholder keys e.g. {{last_working_date}}
     * @return array<string, string>
     */
    public function variablesForEmployee(User $employee, ?Company $company = null, array $overrides = []): array
    {
        $company = $company ?? $employee->company;

        $variables = [
            '{{employee_name}}' => (string) $employee->name,
            '{{employee_id}}' => (string) ($employee->employee_number ?: $employee->id),
            '{{designation}}' => (string) ($employee->designation?->name ?? '—'),
            '{{department}}' => (string) ($employee->department?->name ?? '—'),
            '{{joining_date}}' => $employee->joining_date?->format('d M Y') ?? '—',
            '{{last_working_date}}' => $employee->last_working_date?->format('d M Y') ?? '—',
            '{{company_name}}' => (string) ($company?->name ?? config('app.name')),
            '{{today_date}}' => now()->format('d M Y'),
        ];

        foreach ($overrides as $key => $value) {
            $placeholder = str_starts_with((string) $key, '{{') ? (string) $key : '{{' . $key . '}}';
            $variables[$placeholder] = (string) $value;
        }

        return $variables;
    }

    public function mergePlaceholders(string $html, array $variables): string
    {
        return str_replace(array_keys($variables), array_values($variables), $html);
    }

    public function defaultSubject(string $type, array $variables): string
    {
        $company = $variables['{{company_name}}'] ?? 'Company';
        $employee = $variables['{{employee_name}}'] ?? 'Employee';

        return match ($type) {
            GeneratedLetter::TYPE_RELIEVING => 'Relieving letter — ' . $employee,
            GeneratedLetter::TYPE_EXPERIENCE => 'Experience certificate — ' . $employee,
            GeneratedLetter::TYPE_WARNING => 'Warning letter — ' . $employee,
            GeneratedLetter::TYPE_OFFER => 'Offer letter — ' . $employee,
            default => 'Letter — ' . $employee,
        };
    }

    public function defaultBody(string $type, array $variables): string
    {
        $name = $variables['{{employee_name}}'] ?? 'the employee';
        $company = $variables['{{company_name}}'] ?? 'the company';
        $designation = $variables['{{designation}}'] ?? 'their role';
        $department = $variables['{{department}}'] ?? 'the organization';
        $joining = $variables['{{joining_date}}'] ?? '—';
        $lwd = $variables['{{last_working_date}}'] ?? '—';
        $today = $variables['{{today_date}}'] ?? now()->format('d M Y');

        return match ($type) {
            GeneratedLetter::TYPE_RELIEVING => "<p>To whom it may concern,</p><p>This is to certify that <strong>{$name}</strong> (Employee ID: {$variables['{{employee_id}}']}) was employed with {$company} as {$designation} in {$department}.</p><p>The last working day is recorded as <strong>{$lwd}</strong>. We wish {$name} success in future endeavours.</p><p>Issued on {$today}.</p>",
            GeneratedLetter::TYPE_EXPERIENCE => "<p>To whom it may concern,</p><p>This is to certify that <strong>{$name}</strong> worked with {$company} as {$designation} from {$joining} until {$lwd}.</p><p>During this period, {$name} performed duties assigned in {$department} to the best of our knowledge.</p><p>Issued on {$today}.</p>",
            GeneratedLetter::TYPE_WARNING => "<p>Dear {$name},</p><p>This letter serves as a formal warning regarding conduct/performance matters discussed with you. Please treat this as an opportunity to improve and align with company expectations.</p><p>Issued on {$today}.</p>",
            GeneratedLetter::TYPE_OFFER => "<p>Dear {$name},</p><p>We are pleased to offer you the position of <strong>{$designation}</strong> with {$company}, effective from the date mentioned in your appointment letter.</p><p>We look forward to your contribution in {$department}.</p><p>Issued on {$today}.</p>",
            default => "<p>Dear {$name},</p><p>Please find the official letter from {$company}.</p><p>Issued on {$today}.</p>",
        };
    }

    /**
     * @return array{header: ?string, body: string, footer: ?string}
     */
    public function renderParts(?LetterHeadTemplate $template, string $bodyHtml, array $variables, ?Company $company = null): array
    {
        $header = $template?->header_html;
        if (! $header && $company?->name) {
            $header = '<div style="text-align:center;"><strong>' . e($company->name) . '</strong></div>';
        }

        return [
            'header' => $header ? $this->mergePlaceholders($header, $variables) : null,
            'body' => $this->mergePlaceholders($bodyHtml, $variables),
            'footer' => $template?->footer_html
                ? $this->mergePlaceholders($template->footer_html, $variables)
                : null,
        ];
    }
}
