import React, { useCallback, useEffect, useState } from 'react';

import { useAppStateContext } from '../../context/user.data.context';
import {
  listPromptTemplates,
  createPromptTemplate,
  updatePromptTemplate,
  deletePromptTemplate,
  improvePrompt,
} from '../../service/content-generator/content-generator.service';
import type { PromptTemplate } from '../../service/content-generator/content-generator.interface';

import {
  EMPTY_PROMPT_TEMPLATE_DRAFT,
  toPromptTemplateDraft,
  toTemplatePayload,
  type PromptTemplateDraft,
} from './PromptTemplateDraft';

const TONES = [
  { value: 'professional', label: 'Professional' },
  { value: 'friendly', label: 'Friendly' },
  { value: 'luxury', label: 'Luxury' },
  { value: 'technical', label: 'Technical' },
  { value: 'custom', label: 'Custom…' },
];

const LANGUAGES = [
  { value: 'en', label: 'English' },
  { value: 'ro', label: 'Romanian' },
  { value: 'de', label: 'German' },
  { value: 'fr', label: 'French' },
  { value: 'es', label: 'Spanish' },
  { value: 'it', label: 'Italian' },
  { value: 'nl', label: 'Dutch' },
  { value: 'pt', label: 'Portuguese' },
  { value: 'pl', label: 'Polish' },
  { value: 'el', label: 'Greek' },
  { value: 'tr', label: 'Turkish' },
  { value: 'hu', label: 'Hungarian' },
  { value: 'cs', label: 'Czech' },
  { value: 'sv', label: 'Swedish' },
  { value: 'da', label: 'Danish' },
  { value: 'fi', label: 'Finnish' },
  { value: 'no', label: 'Norwegian' },
  { value: 'bg', label: 'Bulgarian' },
  { value: 'hr', label: 'Croatian' },
  { value: 'ar', label: 'Arabic' },
];

const PROMPT_FIELDS: {
  key: keyof Pick<
    PromptTemplateDraft,
    'titles_prompt' | 'descriptions_prompt' | 'tags_prompt' | 'faq_prompt'
  >;
  label: string;
  placeholder: string;
  fieldName: string;
  maxLength: number;
}[] = [
  {
    key: 'titles_prompt',
    label: 'Titles',
    placeholder: 'e.g., Always start with the brand name, max 70 characters…',
    fieldName: 'titles',
    maxLength: 1500,
  },
  {
    key: 'descriptions_prompt',
    label: 'Descriptions',
    placeholder:
      'e.g., Include a benefits section, use bullet points, max 200 words…',
    fieldName: 'descriptions',
    maxLength: 4500,
  },
  {
    key: 'tags_prompt',
    label: 'Tags',
    placeholder: 'e.g., Include seasonal tags, max 8 tags, comma-separated…',
    fieldName: 'tags',
    maxLength: 1500,
  },
  {
    key: 'faq_prompt',
    label: 'FAQ',
    placeholder:
      'e.g., Focus on shipping and returns questions, 3-5 Q&A pairs…',
    fieldName: 'faq',
    maxLength: 1500,
  },
];

interface ConfirmModalProps {
  open: boolean;
  message: string;
  onConfirm: () => void;
  onCancel: () => void;
  busy?: boolean;
}

const ConfirmModal = ({
  open,
  message,
  onConfirm,
  onCancel,
  busy,
}: ConfirmModalProps): JSX.Element | null => {
  if (!open) return null;
  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4">
      <div className="w-full max-w-sm rounded-xl border border-gray-200 bg-white p-6 shadow-xl">
        <p className="text-sm text-gray-800">{message}</p>
        <div className="mt-5 flex justify-end gap-3">
          <button
            type="button"
            onClick={onCancel}
            disabled={busy}
            className="rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50"
          >
            Cancel
          </button>
          <button
            type="button"
            onClick={onConfirm}
            disabled={busy}
            className="rounded-md bg-red-600 px-4 py-2 text-sm font-medium text-white hover:bg-red-700 disabled:opacity-50"
          >
            {busy ? 'Deleting…' : 'Delete'}
          </button>
        </div>
      </div>
    </div>
  );
};

const PAGE_SIZE = 10;

const PromptTemplates = (): JSX.Element => {
  const { clientId } = useAppStateContext();

  const [view, setView] = useState<'list' | 'form'>('list');
  const [templates, setTemplates] = useState<PromptTemplate[]>([]);
  const [loading, setLoading] = useState(false);
  const [listError, setListError] = useState<string | null>(null);
  const [nextCursor, setNextCursor] = useState<string | null>(null);
  const [prevCursors, setPrevCursors] = useState<string[]>([]);

  const [draft, setDraft] = useState<PromptTemplateDraft>(
    EMPTY_PROMPT_TEMPLATE_DRAFT
  );
  const [saving, setSaving] = useState(false);
  const [formError, setFormError] = useState<string | null>(null);

  const [deleteId, setDeleteId] = useState<string | null>(null);
  const [deleteTemplateName, setDeleteTemplateName] = useState('');
  const [deleteBusy, setDeleteBusy] = useState(false);

  const [improvingField, setImprovingField] = useState<string | null>(null);

  const fetchPage = useCallback(
    async (cursor?: string | null) => {
      if (!clientId) return;
      setLoading(true);
      setListError(null);
      try {
        const res = await listPromptTemplates(clientId, cursor);
        if (res?.data) {
          setTemplates(res.data.templates);
          setNextCursor(res.data.next_cursor);
        } else {
          setListError(res?.error || 'Failed to load templates.');
        }
      } catch {
        setListError('Failed to load templates.');
      } finally {
        setLoading(false);
      }
    },
    [clientId]
  );

  useEffect(() => {
    fetchPage(null);
  }, [fetchPage]);

  const handleNext = () => {
    if (!nextCursor) return;
    setPrevCursors(prev => [...prev, /* current offset */ '']);
    fetchPage(nextCursor);
  };

  const handlePrev = () => {
    const cursors = [...prevCursors];
    cursors.pop();
    setPrevCursors(cursors);
    fetchPage(cursors[cursors.length - 1] ?? null);
  };

  const openCreate = () => {
    setDraft(EMPTY_PROMPT_TEMPLATE_DRAFT);
    setFormError(null);
    setView('form');
  };

  const openEdit = (template: PromptTemplate) => {
    setDraft(toPromptTemplateDraft(template));
    setFormError(null);
    setView('form');
  };

  const handleSave = async () => {
    if (!clientId) return;
    if (!draft.name.trim()) {
      setFormError('Template name is required.');
      return;
    }
    setSaving(true);
    setFormError(null);
    try {
      const payload = toTemplatePayload(draft);
      const res = draft.template_id
        ? await updatePromptTemplate(draft.template_id, payload, clientId)
        : await createPromptTemplate(payload, clientId);
      if (res?.error || res?.errors) {
        setFormError(
          (res.error ||
            String(res.errors) ||
            'Failed to save template.') as string
        );
        return;
      }
      setView('list');
      fetchPage(null);
      setPrevCursors([]);
    } catch {
      setFormError('Failed to save template.');
    } finally {
      setSaving(false);
    }
  };

  const handleDelete = async () => {
    if (!clientId || !deleteId) return;
    setDeleteBusy(true);
    try {
      await deletePromptTemplate(deleteId, clientId);
      setDeleteId(null);
      fetchPage(null);
      setPrevCursors([]);
    } catch {
      /* ignore */
    } finally {
      setDeleteBusy(false);
    }
  };

  const handleImproveField = async (
    fieldKey: keyof Pick<
      PromptTemplateDraft,
      'titles_prompt' | 'descriptions_prompt' | 'tags_prompt' | 'faq_prompt'
    >,
    fieldName: string
  ) => {
    if (!clientId) return;
    const current = draft[fieldKey];
    if (!current.trim()) return;
    setImprovingField(fieldKey);
    try {
      const res = await improvePrompt(
        current,
        fieldName,
        draft.language,
        clientId
      );
      const improved = res?.data?.improved_prompt;
      if (improved) {
        setDraft(prev => ({ ...prev, [fieldKey]: improved }));
      }
    } catch {
      /* ignore */
    } finally {
      setImprovingField(null);
    }
  };

  if (view === 'form') {
    return (
      <div className="mx-auto w-full max-w-3xl space-y-6 bg-white">
        <div className="flex items-center gap-3">
          <button
            type="button"
            onClick={() => setView('list')}
            className="text-sm text-gray-500 hover:text-gray-900"
          >
            ← Back
          </button>
          <h2 className="text-base font-semibold text-gray-900">
            {draft.template_id ? 'Edit Template' : 'New Template'}
          </h2>
        </div>

        <div className="rounded-lg border border-gray-200 bg-white p-6 space-y-5">
          <div className="space-y-2">
            <label className="block text-sm font-medium text-gray-900">
              Template Name <span className="text-red-500">*</span>
            </label>
            <input
              type="text"
              value={draft.name}
              onChange={e =>
                setDraft(prev => ({ ...prev, name: e.target.value }))
              }
              placeholder="e.g., Electronics – English"
              className="block w-full rounded-md border-gray-300 px-3 py-2 text-sm focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900"
            />
          </div>

          <div className="space-y-2">
            <label className="block text-sm font-medium text-gray-900">
              Description
            </label>
            <input
              type="text"
              value={draft.description}
              onChange={e =>
                setDraft(prev => ({ ...prev, description: e.target.value }))
              }
              placeholder="Short description for your reference"
              className="block w-full rounded-md border-gray-300 px-3 py-2 text-sm focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900"
            />
          </div>

          <div className="grid grid-cols-1 gap-5 sm:grid-cols-3">
            <div className="space-y-2">
              <label className="block text-sm font-medium text-gray-900">
                Language
              </label>
              <select
                value={draft.language}
                onChange={e =>
                  setDraft(prev => ({ ...prev, language: e.target.value }))
                }
                className="block w-full rounded-md border-gray-300 py-2 pl-3 pr-10 text-sm focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900"
              >
                {LANGUAGES.map(l => (
                  <option key={l.value} value={l.value}>
                    {l.label}
                  </option>
                ))}
              </select>
            </div>

            <div className="space-y-2">
              <label className="block text-sm font-medium text-gray-900">
                Brand Tone
              </label>
              <select
                value={draft.tone}
                onChange={e =>
                  setDraft(prev => ({ ...prev, tone: e.target.value }))
                }
                className="block w-full rounded-md border-gray-300 py-2 pl-3 pr-10 text-sm focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900"
              >
                {TONES.map(t => (
                  <option key={t.value} value={t.value}>
                    {t.label}
                  </option>
                ))}
              </select>
            </div>

            <div className="space-y-2">
              <label className="block text-sm font-medium text-gray-900">
                Creativity
              </label>
              <select
                value={draft.temperature}
                onChange={e =>
                  setDraft(prev => ({ ...prev, temperature: e.target.value }))
                }
                className="block w-full rounded-md border-gray-300 py-2 pl-3 pr-10 text-sm focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900"
              >
                <option value="0.3">Conservative (0.3)</option>
                <option value="0.5">Balanced (0.5)</option>
                <option value="0.7">Default (0.7)</option>
                <option value="0.9">Creative (0.9)</option>
              </select>
            </div>
          </div>

          {draft.tone === 'custom' && (
            <div className="space-y-2">
              <label className="block text-sm font-medium text-gray-900">
                Custom Tone Description
              </label>
              <textarea
                rows={2}
                value={draft.custom_tone}
                onChange={e =>
                  setDraft(prev => ({ ...prev, custom_tone: e.target.value }))
                }
                placeholder="Describe your brand voice in a few sentences…"
                className="block w-full rounded-md border-gray-300 px-3 py-2 text-sm placeholder:text-gray-400 focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900"
              />
            </div>
          )}

          <hr className="border-gray-100" />

          <div className="space-y-4">
            <h3 className="text-sm font-medium text-gray-900">
              Field Instructions
            </h3>
            {PROMPT_FIELDS.map(
              ({ key, label, placeholder, fieldName, maxLength }) => (
                <div key={key} className="space-y-2">
                  <div className="flex items-center justify-between">
                    <label className="block text-sm font-medium text-gray-700">
                      {label}
                    </label>
                    <button
                      type="button"
                      onClick={() => handleImproveField(key, fieldName)}
                      disabled={improvingField === key || !draft[key].trim()}
                      className="text-[10px] font-semibold text-gray-600 hover:text-gray-900 disabled:cursor-not-allowed disabled:opacity-50"
                    >
                      {improvingField === key
                        ? 'Enhancing…'
                        : '✨ Enhance with AI'}
                    </button>
                  </div>
                  <textarea
                    rows={2}
                    value={draft[key]}
                    onChange={e =>
                      setDraft(prev => ({ ...prev, [key]: e.target.value }))
                    }
                    maxLength={maxLength}
                    placeholder={placeholder}
                    className="block w-full rounded-md border-gray-300 px-3 py-2 text-sm placeholder:text-gray-400 focus:border-gray-900 focus:outline-none focus:ring-1 focus:ring-gray-900"
                  />
                  <p className="text-right text-xs text-gray-400">
                    {draft[key].length} / {maxLength}
                  </p>
                </div>
              )
            )}
          </div>

          {formError && (
            <div className="rounded-md bg-red-50 px-4 py-3 text-sm text-red-700 ring-1 ring-inset ring-red-600/20">
              {formError}
            </div>
          )}

          <div className="flex justify-end gap-3 border-t border-gray-100 pt-4">
            <button
              type="button"
              onClick={() => setView('list')}
              disabled={saving}
              className="rounded-md border border-gray-200 bg-white px-5 py-2.5 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:opacity-50"
            >
              Cancel
            </button>
            <button
              type="button"
              onClick={handleSave}
              disabled={saving}
              className="rounded-md bg-gray-900 px-5 py-2.5 text-sm font-medium text-white hover:bg-gray-800 disabled:opacity-50"
            >
              {saving
                ? 'Saving…'
                : draft.template_id
                  ? 'Save Changes'
                  : 'Create Template'}
            </button>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="mx-auto w-full max-w-5xl space-y-6 bg-white">
      <ConfirmModal
        open={!!deleteId}
        message={`Delete "${deleteTemplateName}"? This cannot be undone.`}
        onConfirm={handleDelete}
        onCancel={() => setDeleteId(null)}
        busy={deleteBusy}
      />

      <div className="flex items-center justify-between">
        <div>
          <h2 className="text-base font-semibold text-gray-900">
            Prompt Templates
          </h2>
          <p className="mt-0.5 text-xs text-gray-500">
            Reusable instruction sets you can apply when generating content.
          </p>
        </div>
        <button
          type="button"
          onClick={openCreate}
          className="rounded-md bg-gray-900 px-4 py-2 text-sm font-medium text-white hover:bg-gray-800"
        >
          + New Template
        </button>
      </div>

      {listError && (
        <div className="rounded-md bg-red-50 px-4 py-3 text-sm text-red-700 ring-1 ring-inset ring-red-600/20">
          {listError}
        </div>
      )}

      {loading ? (
        <div className="space-y-3">
          {[1, 2, 3].map(n => (
            <div
              key={n}
              className="h-24 animate-pulse rounded-lg border border-gray-200 bg-gray-50"
            />
          ))}
        </div>
      ) : templates.length === 0 ? (
        <div className="rounded-lg border border-dashed border-gray-300 bg-gray-50 px-6 py-12 text-center">
          <p className="text-sm font-medium text-gray-900">No templates yet</p>
          <p className="mt-1 text-xs text-gray-500">
            Create a template to save your generation settings for reuse.
          </p>
          <button
            type="button"
            onClick={openCreate}
            className="mt-4 rounded-md bg-gray-900 px-4 py-2 text-sm font-medium text-white hover:bg-gray-800"
          >
            Create First Template
          </button>
        </div>
      ) : (
        <div className="space-y-3">
          {templates.map(template => {
            const promptPreviews = [
              { label: 'Titles', value: template.titles_prompt },
              { label: 'Descriptions', value: template.descriptions_prompt },
              { label: 'Tags', value: template.tags_prompt },
              { label: 'FAQ', value: template.faq_prompt },
            ].filter(p => p.value);

            return (
              <div
                key={template.template_id}
                className="rounded-lg border border-gray-200 bg-white p-5"
              >
                <div className="flex items-start justify-between gap-4">
                  <div className="min-w-0 flex-1">
                    <div className="flex flex-wrap items-center gap-2">
                      <h3 className="text-sm font-semibold text-gray-900">
                        {template.name}
                      </h3>
                      <span className="inline-flex items-center rounded-md bg-gray-100 px-2 py-0.5 text-[10px] font-medium uppercase text-gray-600">
                        {template.language}
                      </span>
                      <span className="inline-flex items-center rounded-md bg-gray-100 px-2 py-0.5 text-[10px] font-medium text-gray-600">
                        {template.tone === 'custom'
                          ? 'Custom tone'
                          : template.tone}
                      </span>
                      <span className="inline-flex items-center rounded-md bg-gray-100 px-2 py-0.5 text-[10px] font-medium text-gray-600">
                        temp {template.temperature}
                      </span>
                    </div>
                    {template.description && (
                      <p className="mt-1 text-xs text-gray-500">
                        {template.description}
                      </p>
                    )}
                    {promptPreviews.length > 0 && (
                      <div className="mt-3 flex flex-wrap gap-2">
                        {promptPreviews.map(p => (
                          <span
                            key={p.label}
                            className="inline-flex max-w-[240px] truncate rounded border border-gray-200 bg-gray-50 px-2 py-1 text-[11px] text-gray-700"
                            title={`${p.label}: ${p.value}`}
                          >
                            <span className="mr-1 font-medium">{p.label}:</span>
                            {p.value}
                          </span>
                        ))}
                      </div>
                    )}
                  </div>
                  <div className="flex shrink-0 gap-2">
                    <button
                      type="button"
                      onClick={() => openEdit(template)}
                      className="rounded-md border border-gray-200 bg-white px-3 py-1.5 text-xs font-medium text-gray-700 hover:bg-gray-50"
                    >
                      Edit
                    </button>
                    <button
                      type="button"
                      onClick={() => {
                        setDeleteId(template.template_id);
                        setDeleteTemplateName(template.name);
                      }}
                      className="rounded-md border border-gray-200 bg-white px-3 py-1.5 text-xs font-medium text-red-600 hover:bg-red-50"
                    >
                      Delete
                    </button>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
      )}

      {(prevCursors.length > 0 || nextCursor) && (
        <div className="flex items-center justify-between border-t border-gray-100 pt-4">
          <button
            type="button"
            onClick={handlePrev}
            disabled={prevCursors.length === 0 || loading}
            className="rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
          >
            Previous
          </button>
          <span className="text-xs text-gray-500">
            {templates.length} of {PAGE_SIZE} per page
          </span>
          <button
            type="button"
            onClick={handleNext}
            disabled={!nextCursor || loading}
            className="rounded-md border border-gray-200 bg-white px-4 py-2 text-sm font-medium text-gray-700 hover:bg-gray-50 disabled:cursor-not-allowed disabled:opacity-40"
          >
            Next
          </button>
        </div>
      )}
    </div>
  );
};

export default PromptTemplates;
