<?php

namespace App\Http\Controllers;

use App\Models\ContactList;
use App\Models\Form;
use App\Models\Tag;
use App\Services\ContactFieldRegistry;
use App\Services\FormEmbedBuilder;
use Illuminate\Http\Request;
use Inertia\Inertia;

class FormController extends Controller
{
    public function index()
    {
        $forms = Form::when(request('search'), fn ($q, $s) => $q->where('name', 'like', "%{$s}%"))
            ->when(request('status'), fn ($q, $s) => $q->where('status', $s))
            ->when(request('type'), fn ($q, $t) => $q->where('type', $t))
            ->with(['lists:id,title,color', 'tags:id,title,color'])
            ->latest()
            ->paginate(15)
            ->withQueryString()
            ->through(fn (Form $f) => [
                'id'                 => $f->id,
                'name'               => $f->name,
                'uuid'               => $f->uuid,
                'type'               => $f->type,
                'status'             => $f->status,
                'total_views'        => $f->total_views,
                'total_submissions'  => $f->total_submissions,
                'submission_rate'    => $f->submissionRate(),
                'lists'              => $f->lists,
                'tags'               => $f->tags,
                'style'              => $f->style,
                'created_at'         => $f->created_at->toISOString(),
            ]);

        return Inertia::render('Forms/Index', [
            'forms'   => $forms,
            'filters' => request()->only(['search', 'status', 'type']),
        ]);
    }

    public function create(Request $request)
    {
        $type = in_array($request->query('type'), ['inline', 'popup'], true) ? $request->query('type') : 'inline';

        return Inertia::render('Forms/Builder', [
            'type'          => $type,
            'form'          => null,
            'allLists'      => ContactList::orderBy('title')->get(['id', 'title', 'color']),
            'allTags'       => Tag::orderBy('title')->get(['id', 'title', 'color']),
            'fieldRegistry' => ContactFieldRegistry::FIELDS,
        ]);
    }

    public function edit(Form $form)
    {
        return Inertia::render('Forms/Builder', [
            'type'          => $form->type,
            'form'          => $this->present($form),
            'allLists'      => ContactList::orderBy('title')->get(['id', 'title', 'color']),
            'allTags'       => Tag::orderBy('title')->get(['id', 'title', 'color']),
            'fieldRegistry' => ContactFieldRegistry::FIELDS,
        ]);
    }

    private function rules(): array
    {
        return [
            'name'       => 'required|string|max:255',
            'type'       => 'required|in:inline,popup',
            'status'     => 'required|in:draft,active,paused',
            'fields'     => 'nullable|array',
            'settings'   => 'nullable|array',
            'style'      => 'nullable|array',
            'list_ids'   => 'nullable|array',
            'list_ids.*' => 'exists:lists,id',
            'tag_ids'    => 'nullable|array',
            'tag_ids.*'  => 'exists:tags,id',
        ];
    }

    public function store(Request $request)
    {
        $data = $request->validate($this->rules());

        $form = Form::create([
            'name'     => $data['name'],
            'type'     => $data['type'],
            'status'   => $data['status'],
            'fields'   => $data['fields'] ?? [],
            'settings' => $data['settings'] ?? [],
            'style'    => $data['style'] ?? [],
        ]);

        $form->lists()->sync($data['list_ids'] ?? []);
        $form->tags()->sync($data['tag_ids'] ?? []);

        return redirect()->route('forms.edit', $form)->with('success', 'Form created successfully.');
    }

    public function update(Request $request, Form $form)
    {
        $data = $request->validate($this->rules());

        $form->fill([
            'name'     => $data['name'],
            'type'     => $data['type'],
            'status'   => $data['status'],
            'fields'   => $data['fields'] ?? [],
            'settings' => $data['settings'] ?? [],
            'style'    => $data['style'] ?? [],
        ])->save();

        $form->lists()->sync($data['list_ids'] ?? []);
        $form->tags()->sync($data['tag_ids'] ?? []);

        return redirect()->route('forms.edit', $form)->with('success', 'Form saved successfully.');
    }

    public function destroy(Form $form)
    {
        $form->delete();

        return redirect()->route('forms.index')->with('success', 'Form deleted successfully.');
    }

    public function duplicate(Form $form)
    {
        $copy = $form->replicate(['uuid', 'total_views', 'total_submissions']);
        $copy->name = $form->name . ' (Copy)';
        $copy->status = 'draft';
        $copy->save();

        $copy->lists()->sync($form->lists->pluck('id'));
        $copy->tags()->sync($form->tags->pluck('id'));

        return redirect()->route('forms.index')->with('success', 'Form duplicated successfully.');
    }

    public function embed(Form $form)
    {
        return response()->json($this->embedPayload($form));
    }

    public function show(Form $form)
    {
        $form->load(['lists:id,title,color', 'tags:id,title,color']);

        $submissions = $form->submissions()
            ->with('contact:id,first_name,last_name,email')
            ->latest()
            ->paginate(15, ['*'], 'submissions_page')
            ->through(fn ($s) => [
                'id'         => $s->id,
                'email'      => $s->email,
                'name'       => trim(($s->contact->first_name ?? '') . ' ' . ($s->contact->last_name ?? '')),
                'contact_id' => $s->contact_id,
                'created_at' => $s->created_at->toISOString(),
            ]);

        return Inertia::render('Forms/Show', [
            'form' => [
                'id'                 => $form->id,
                'name'               => $form->name,
                'uuid'               => $form->uuid,
                'type'               => $form->type,
                'status'             => $form->status,
                'total_views'        => $form->total_views,
                'total_submissions'  => $form->total_submissions,
                'submission_rate'    => $form->submissionRate(),
                'lists'              => $form->lists,
                'tags'               => $form->tags,
                'created_at'         => $form->created_at->toISOString(),
                'updated_at'         => $form->updated_at->toISOString(),
                'embed'              => $this->embedPayload($form),
            ],
            'submissions' => $submissions,
        ]);
    }

    public function bulkDestroy(Request $request)
    {
        $ids = $request->validate([
            'ids'   => 'required|array',
            'ids.*' => 'exists:forms,id',
        ])['ids'];

        Form::whereIn('id', $ids)->delete();

        return redirect()->route('forms.index')->with('success', 'Selected forms deleted.');
    }

    public function bulkToggleStatus(Request $request)
    {
        $data = $request->validate([
            'ids'     => 'required|array',
            'ids.*'   => 'exists:forms,id',
            'status'  => 'required|in:draft,active,paused',
        ]);

        Form::whereIn('id', $data['ids'])->update(['status' => $data['status']]);

        return redirect()->route('forms.index')->with('success', 'Forms status updated.');
    }

    private function present(Form $form): array
    {
        return [
            'id'         => $form->id,
            'name'       => $form->name,
            'uuid'       => $form->uuid,
            'type'       => $form->type,
            'status'     => $form->status,
            'fields'     => $form->fields,
            'settings'   => $form->settings,
            'style'      => $form->style,
            'list_ids'   => $form->lists->pluck('id'),
            'tag_ids'    => $form->tags->pluck('id'),
            'total_views'       => $form->total_views,
            'total_submissions' => $form->total_submissions,
            'embed'      => $this->embedPayload($form),
        ];
    }

    private function embedPayload(Form $form): array
    {
        $snippet = $form->type === 'popup'
            ? '<script async src="' . $form->popupScriptUrl() . '"></script>'
            : '<div id="' . $form->embedTargetId() . '"></div>' . "\n"
                . '<script async src="' . $form->inlineScriptUrl() . '"></script>';

        return [
            'type'         => $form->type,
            'status'       => $form->status,
            'snippet'      => $snippet,
            'preview_html' => FormEmbedBuilder::inlineHtml($form),
            'submit_url'   => $form->submitUrl(),
        ];
    }
}
