<?php

namespace App\Services;

/**
 * Renders a Form's block tree (the same shape produced by
 * resources/js/Components/FormEditor/*, itself a clone of the Campaign/
 * Template block editor - see EmailRenderer.php for the analogous email
 * renderer) into plain div/flex HTML. Unlike EmailRenderer, no MSO/table
 * scaffolding is needed since this is rendered in a normal browser, not an
 * email client.
 */
class FormRenderer
{
    public static function render(array $blocks): string
    {
        $html = '';
        foreach ($blocks as $block) {
            if (($block['type'] ?? '') === 'body') {
                continue;
            }
            $html .= self::renderBlock($block);
        }

        return $html;
    }

    public static function bodySettings(array $blocks): array
    {
        foreach ($blocks as $block) {
            if (($block['type'] ?? '') === 'body') {
                return $block;
            }
        }

        return [];
    }

    private static function renderBlock(array $block): string
    {
        $type = $block['type'] ?? '';
        $s    = $block['styles'] ?? [];

        $wrapStyle = self::wrapStyle($s, $type);

        if (str_starts_with($type, 'field-')) {
            return self::renderField($block, $wrapStyle);
        }

        return match ($type) {
            'text'          => self::renderText($block, $wrapStyle),
            'heading'       => self::renderHeading($block, $wrapStyle),
            'image'         => self::renderImage($block, $wrapStyle),
            'logo'          => self::renderLogo($block, $wrapStyle),
            'button'        => self::renderLinkButton($block, $wrapStyle),
            'submit-button' => self::renderSubmitButton($block, $wrapStyle),
            'divider'       => self::renderDivider($block, $wrapStyle),
            'spacer'        => self::renderSpacer($block),
            'column'        => self::renderColumn($block, $wrapStyle),
            'html'          => '<div style="' . $wrapStyle . '">' . ($block['html'] ?? '') . '</div>',
            default         => '',
        };
    }

    private static function wrapStyle(array $s, string $type): string
    {
        $pt = $s['paddingTop']    ?? 12;
        $pr = $s['paddingRight']  ?? 0;
        $pb = $s['paddingBottom'] ?? 12;
        $pl = $s['paddingLeft']   ?? 0;
        $mt = $s['marginTop']     ?? 0;
        $mb = $s['marginBottom']  ?? 0;
        $ml = $s['marginLeft']    ?? 0;
        $mr = $s['marginRight']   ?? 0;

        $widthStyle = '';
        if (isset($s['width']) && $s['width'] !== 'auto' && !in_array($type, ['button', 'submit-button', 'logo'], true)) {
            $wVal = (int) $s['width'];
            if ($wVal < 100) {
                $align = $s['blockAlign'] ?? 'left';
                if ($align === 'center') { $ml = 'auto'; $mr = 'auto'; }
                elseif ($align === 'right') { $ml = 'auto'; $mr = 0; }
                else { $ml = 0; $mr = 'auto'; }
                $widthStyle = "width:{$wVal}%;box-sizing:border-box;";
            }
        }

        $mlStr = $ml === 'auto' ? 'auto' : "{$ml}px";
        $mrStr = $mr === 'auto' ? 'auto' : "{$mr}px";

        $style = "box-sizing:border-box;padding:{$pt}px {$pr}px {$pb}px {$pl}px;margin:{$mt}px {$mrStr} {$mb}px {$mlStr};{$widthStyle}";

        if (!empty($s['bgColor'])) {
            $style .= "background:{$s['bgColor']};";
        }
        if (!empty($s['borderRadius']) && !in_array($type, ['button', 'submit-button'], true)) {
            $style .= "border-radius:{$s['borderRadius']}px;";
        }
        if (!empty($s['borderWidth'])) {
            $style .= "border:{$s['borderWidth']}px solid " . ($s['borderColor'] ?? '#e5e7eb') . ';';
        }

        return $style;
    }

    private static function renderText(array $block, string $wrapStyle): string
    {
        $s       = $block['styles'] ?? [];
        $color   = $s['color']     ?? '#374151';
        $size    = $s['fontSize']  ?? 14;
        $align   = $s['textAlign'] ?? 'left';
        $lh      = $s['lineHeight'] ?? 1.6;
        $content = nl2br(e($block['content'] ?? ''));

        return "<div style=\"{$wrapStyle}\"><p style=\"margin:0;color:{$color};font-size:{$size}px;text-align:{$align};line-height:{$lh}\">{$content}</p></div>";
    }

    private static function renderHeading(array $block, string $wrapStyle): string
    {
        $s       = $block['styles'] ?? [];
        $color   = $s['color']      ?? '#111827';
        $size    = $s['fontSize']   ?? 24;
        $align   = $s['textAlign']  ?? 'left';
        $weight  = $s['fontWeight'] ?? 700;
        $content = e($block['content'] ?? '');

        return "<div style=\"{$wrapStyle}\"><h2 style=\"margin:0;color:{$color};font-size:{$size}px;text-align:{$align};font-weight:{$weight};\">{$content}</h2></div>";
    }

    private static function renderImage(array $block, string $wrapStyle): string
    {
        $s     = $block['styles'] ?? [];
        $src   = $block['src']    ?? '';
        $alt   = e($block['alt']  ?? '');
        $align = $s['blockAlign'] ?? $s['textAlign'] ?? 'center';
        $width = $s['width']      ?? 100;
        $link  = $block['link']   ?? '';

        if (!$src) {
            return "<div style=\"{$wrapStyle}text-align:{$align}\"></div>";
        }

        $src      = e($src);
        $widthVal = $width === 'auto' ? 'auto' : "{$width}%";
        $img      = "<img src=\"{$src}\" alt=\"{$alt}\" style=\"max-width:100%;width:{$widthVal};display:inline-block;\" />";
        $content  = $link ? '<a href="' . e($link) . '" target="_blank" rel="noopener" style="text-decoration:none;">' . $img . '</a>' : $img;

        return "<div style=\"{$wrapStyle}text-align:{$align}\">{$content}</div>";
    }

    private static function renderLogo(array $block, string $wrapStyle): string
    {
        $s     = $block['styles'] ?? [];
        $align = $s['blockAlign'] ?? 'center';
        $html  = '';

        if (($block['logoType'] ?? 'text') !== 'text' && !empty($block['src'])) {
            $width = $s['width'] ?? 50;
            $html .= '<img src="' . e($block['src']) . '" alt="' . e($block['alt'] ?? '') . '" style="max-width:100%;width:' . $width . '%;display:inline-block;" />';
        }
        if (($block['logoType'] ?? 'text') !== 'image') {
            $fontFamily = $s['fontFamily'] ?? 'sans-serif';
            $fontWeight = $s['fontWeight'] ?? 'bold';
            $fontSize   = $s['fontSize']   ?? 22;
            $color      = $s['color']      ?? '#111827';
            $html .= '<span style="font-family:' . e($fontFamily) . ';font-weight:' . e((string) $fontWeight) . ';font-size:' . $fontSize . 'px;color:' . $color . '">' . e($block['brandText'] ?? 'Your Brand') . '</span>';
        }

        return "<div style=\"{$wrapStyle}text-align:{$align}\">{$html}</div>";
    }

    private static function renderLinkButton(array $block, string $wrapStyle): string
    {
        $s      = $block['styles'] ?? [];
        $text   = e($block['text'] ?? 'Click here');
        $href   = e($block['href'] ?? '#');
        $bg     = $s['backgroundColor'] ?? '#374151';
        $color  = $s['textColor']       ?? '#ffffff';
        $radius = ($s['borderRadius']   ?? 6) . 'px';
        $size   = ($s['fontSize']       ?? 15) . 'px';
        $align  = $s['blockAlign']      ?? $s['textAlign'] ?? 'left';

        return "<div style=\"{$wrapStyle}text-align:{$align}\"><a href=\"{$href}\" target=\"_blank\" rel=\"noopener\" style=\"display:inline-block;background:{$bg};color:{$color};border-radius:{$radius};font-size:{$size};font-weight:600;padding:10px 24px;text-decoration:none;\">{$text}</a></div>";
    }

    private static function renderSubmitButton(array $block, string $wrapStyle): string
    {
        $s      = $block['styles'] ?? [];
        $text   = e($block['text'] ?? 'Subscribe');
        $bg     = $s['backgroundColor'] ?? '#4285F4';
        $color  = $s['textColor']       ?? '#ffffff';
        $radius = ($s['borderRadius']   ?? 8) . 'px';
        $size   = ($s['fontSize']       ?? 15) . 'px';

        return "<div style=\"{$wrapStyle}\"><button type=\"submit\" class=\"crmfic-submit\" style=\"display:block;width:100%;box-sizing:border-box;background:{$bg};color:{$color};border:none;border-radius:{$radius};font-size:{$size};font-weight:600;padding:12px 24px;cursor:pointer;\">{$text}</button></div>";
    }

    private static function renderDivider(array $block, string $wrapStyle): string
    {
        $s      = $block['styles'] ?? [];
        $color  = $s['borderColor'] ?? '#e5e7eb';
        $bw     = ($s['dividerThickness'] ?? 1) . 'px';
        $bstyle = $s['borderStyle'] ?? 'solid';

        return "<div style=\"{$wrapStyle}\"><hr style=\"border:none;border-top:{$bw} {$bstyle} {$color};width:100%;margin:0;\" /></div>";
    }

    private static function renderSpacer(array $block): string
    {
        $height = ($block['styles']['height'] ?? 15) . 'px';

        return "<div style=\"height:{$height};\"></div>";
    }

    private static function renderColumn(array $block, string $wrapStyle): string
    {
        $columnCount = $block['columnCount'] ?? 2;
        $columns     = $block['columns']     ?? [];
        $colWidths   = $block['colWidths']   ?? [];
        $gap         = 16;

        $cells = '';
        foreach ($columns as $idx => $col) {
            $inner    = self::render($col['blocks'] ?? []);
            $pct      = $colWidths[$idx] ?? round(100 / max(1, $columnCount), 2);
            $firstPad = $idx === 0 ? '' : "padding-left:{$gap}px;";
            $cells   .= "<div style=\"flex:0 0 {$pct}%;max-width:{$pct}%;box-sizing:border-box;{$firstPad}\">{$inner}</div>";
        }

        return "<div style=\"{$wrapStyle}display:flex;flex-wrap:wrap;\">{$cells}</div>";
    }

    private static function renderField(array $block, string $wrapStyle): string
    {
        $id       = e($block['id'] ?? '');
        $type     = $block['type'];
        $label    = e($block['label'] ?? '');
        $required = !empty($block['required']);
        $req      = $required ? ' required' : '';
        $reqMark  = $required ? ' <span class="crmfic-required">*</span>' : '';
        $help     = !empty($block['help']) ? '<div class="crmfic-help">' . e($block['help']) . '</div>' : '';
        $placeholder = e($block['placeholder'] ?? '');
        $radius   = ($block['styles']['borderRadius'] ?? 6) . 'px';
        $inputCss = 'border-radius:' . $radius . ';';

        if ($type === 'field-hidden') {
            return '<input type="hidden" name="' . $id . '" value="' . e($block['value'] ?? '') . '">';
        }

        if ($type === 'field-consent') {
            return "<div style=\"{$wrapStyle}\">"
                . '<label class="crmfic-consent"><input type="checkbox" name="' . $id . '" value="1"' . $req . '> ' . $label . $reqMark . '</label>'
                . $help . '</div>';
        }

        $input = match ($type) {
            'field-textarea' => '<textarea name="' . $id . '" class="crmfic-input" style="' . $inputCss . '" placeholder="' . $placeholder . '"' . $req . '></textarea>',
            'field-name'     => '<div class="crmfic-name-row">'
                . '<input type="text" name="' . $id . '_first" class="crmfic-input" style="' . $inputCss . '" placeholder="First name"' . $req . '>'
                . '<input type="text" name="' . $id . '_second" class="crmfic-input" style="' . $inputCss . '" placeholder="Last name">'
                . '</div>',
            'field-number'   => '<input type="number" name="' . $id . '" class="crmfic-input" style="' . $inputCss . '" placeholder="' . $placeholder . '"' . $req . '>',
            'field-date'     => '<input type="date" name="' . $id . '" class="crmfic-input" style="' . $inputCss . '"' . $req . '>',
            'field-website'  => '<input type="url" name="' . $id . '" class="crmfic-input" style="' . $inputCss . '" placeholder="' . $placeholder . '"' . $req . '>',
            'field-phone'    => '<input type="tel" name="' . $id . '" class="crmfic-input" style="' . $inputCss . '" placeholder="' . $placeholder . '"' . $req . '>',
            'field-email'    => '<input type="email" name="' . $id . '" class="crmfic-input" style="' . $inputCss . '" placeholder="' . $placeholder . '"' . $req . '>',
            'field-dropdown' => self::renderDropdown($id, $block, $req, $inputCss),
            'field-radio'    => self::renderRadio($id, $block, $required),
            'field-checkbox' => self::renderCheckboxGroup($id, $block),
            'field-rating'   => self::renderRating($id, $req),
            default          => '<input type="text" name="' . $id . '" class="crmfic-input" style="' . $inputCss . '" placeholder="' . $placeholder . '"' . $req . '>',
        };

        return "<div style=\"{$wrapStyle}\">"
            . '<label class="crmfic-label">' . $label . $reqMark . '</label>'
            . $input . $help . '</div>';
    }

    private static function renderDropdown(string $id, array $block, string $req, string $inputCss): string
    {
        $options     = array_map(fn ($o) => '<option value="' . e($o) . '">' . e($o) . '</option>', $block['options'] ?? []);
        $placeholder = e($block['placeholder'] ?? 'Select an option');

        return '<select name="' . $id . '" class="crmfic-input" style="' . $inputCss . '"' . $req . '><option value="">' . $placeholder . '</option>' . implode('', $options) . '</select>';
    }

    private static function renderRadio(string $id, array $block, bool $required): string
    {
        $options = $block['options'] ?? [];

        if (($block['displayAs'] ?? 'list') === 'buttons') {
            $color = $block['styles']['color'] ?? '#374151';
            $radius = ($block['styles']['borderRadius'] ?? 999);
            $html = '<div class="crmfic-choice-buttons">';
            foreach ($options as $i => $option) {
                $req = ($required && $i === 0) ? ' required' : '';
                $html .= '<label class="crmfic-choice-btn" style="border-radius:' . $radius . 'px"><input type="radio" name="' . $id . '" value="' . e($option) . '"' . $req . '> <span style="background:' . e($color) . '">' . e($option) . '</span></label>';
            }

            return $html . '</div>';
        }

        $html = '<div class="crmfic-radio-group">';
        foreach ($options as $i => $option) {
            $req = ($required && $i === 0) ? ' required' : '';
            $html .= '<label class="crmfic-choice"><input type="radio" name="' . $id . '" value="' . e($option) . '"' . $req . '> ' . e($option) . '</label>';
        }

        return $html . '</div>';
    }

    private static function renderCheckboxGroup(string $id, array $block): string
    {
        $options = $block['options'] ?? [];
        $html = '<div class="crmfic-checkbox-group">';
        foreach ($options as $option) {
            $html .= '<label class="crmfic-choice"><input type="checkbox" name="' . $id . '[]" value="' . e($option) . '"> ' . e($option) . '</label>';
        }

        return $html . '</div>';
    }

    private static function renderRating(string $id, string $req): string
    {
        $html = '<div class="crmfic-rating">';
        for ($i = 5; $i >= 1; $i--) {
            $html .= '<input type="radio" name="' . $id . '" value="' . $i . '" id="' . $id . '_' . $i . '"' . ($i === 5 ? $req : '') . '>'
                . '<label for="' . $id . '_' . $i . '">&#9733;</label>';
        }

        return $html . '</div>';
    }
}
