'use client';

import * as React from 'react';

export interface DevCrudField {
  key: string;
  label: string;
  placeholder?: string;
}

export interface DevCrudConsoleProps {
  title: string;
  entity: string;
  fields: DevCrudField[];
}

type RecordValue = Record<string, unknown> & { id: string };

function stringifyValue(value: unknown) {
  if (value === null || value === undefined) {
    return '';
  }
  if (typeof value === 'object') {
    return JSON.stringify(value);
  }
  return String(value);
}

function parseValue(value: string) {
  const trimmed = value.trim();
  if (!trimmed) {
    return '';
  }
  if (trimmed === 'true') {
    return true;
  }
  if (trimmed === 'false') {
    return false;
  }
  if (!Number.isNaN(Number(trimmed)) && trimmed !== '') {
    return Number(trimmed);
  }
  if ((trimmed.startsWith('{') && trimmed.endsWith('}')) || (trimmed.startsWith('[') && trimmed.endsWith(']'))) {
    try {
      return JSON.parse(trimmed);
    } catch {
      return trimmed;
    }
  }
  return trimmed;
}

export function DevCrudConsole({ title, entity, fields }: DevCrudConsoleProps) {
  const [records, setRecords] = React.useState<RecordValue[]>([]);
  const [selectedId, setSelectedId] = React.useState<string>('');
  const [formValues, setFormValues] = React.useState<Record<string, string>>({});
  const [status, setStatus] = React.useState<string>('Carregando base local...');
  const [busy, setBusy] = React.useState(false);

  const resetForm = React.useCallback(() => {
    const next: Record<string, string> = {};
    fields.forEach((field) => {
      next[field.key] = '';
    });
    setFormValues(next);
    setSelectedId('');
  }, [fields]);

  const load = React.useCallback(async () => {
    setBusy(true);
    const response = await fetch(`/api/dev-db/${entity}`, { cache: 'no-store' });
    const payload = (await response.json()) as { records: RecordValue[] };
    setRecords(payload.records ?? []);
    setStatus(`Base local sincronizada: ${payload.records?.length ?? 0} registro(s).`);
    setBusy(false);
  }, [entity]);

  React.useEffect(() => {
    resetForm();
    void load();
  }, [load, resetForm]);

  const handleSelect = React.useCallback(
    (record: RecordValue) => {
      setSelectedId(record.id);
      const next: Record<string, string> = {};
      fields.forEach((field) => {
        next[field.key] = stringifyValue(record[field.key]);
      });
      setFormValues(next);
      setStatus(`Registro ${record.id} carregado para edicao.`);
    },
    [fields],
  );

  const buildPayload = React.useCallback(() => {
    const payload: Record<string, unknown> = {};
    fields.forEach((field) => {
      const rawValue = formValues[field.key] ?? '';
      if (rawValue.trim()) {
        payload[field.key] = parseValue(rawValue);
      }
    });
    return payload;
  }, [fields, formValues]);

  const createRecord = React.useCallback(async () => {
    setBusy(true);
    const response = await fetch(`/api/dev-db/${entity}`, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(buildPayload()),
    });
    const payload = (await response.json()) as { record?: RecordValue };
    setStatus(`Registro criado: ${payload.record?.id ?? 'sem id'}.`);
    resetForm();
    await load();
    setBusy(false);
  }, [buildPayload, entity, load, resetForm]);

  const updateRecord = React.useCallback(async () => {
    if (!selectedId) {
      setStatus('Selecione um registro para editar.');
      return;
    }

    setBusy(true);
    const response = await fetch(`/api/dev-db/${entity}/${selectedId}`, {
      method: 'PUT',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(buildPayload()),
    });
    const payload = (await response.json()) as { record?: RecordValue; error?: string };
    setStatus(payload.error ? `Falha: ${payload.error}` : `Registro atualizado: ${payload.record?.id ?? selectedId}.`);
    await load();
    setBusy(false);
  }, [buildPayload, entity, load, selectedId]);

  const deleteRecord = React.useCallback(async () => {
    if (!selectedId) {
      setStatus('Selecione um registro para excluir.');
      return;
    }

    setBusy(true);
    const response = await fetch(`/api/dev-db/${entity}/${selectedId}`, { method: 'DELETE' });
    const payload = (await response.json()) as { record?: RecordValue; error?: string };
    setStatus(payload.error ? `Falha: ${payload.error}` : `Registro excluido: ${payload.record?.id ?? selectedId}.`);
    resetForm();
    await load();
    setBusy(false);
  }, [entity, load, resetForm, selectedId]);

  return (
    <section className="rounded-[1.6rem] border border-slate-200 bg-white p-5">
      <div className="flex flex-col gap-3 lg:flex-row lg:items-start lg:justify-between">
        <div>
          <p className="text-[11px] font-black uppercase tracking-[0.24em] text-slate-500">Crud local interno</p>
          <h3 className="mt-2 text-xl font-black tracking-tight text-slate-900">{title}</h3>
          <p className="mt-2 text-sm leading-6 text-slate-600">
            Esta area grava em `storage/local-dev-db.json` enquanto o PostgreSQL externo nao estiver liberado.
          </p>
        </div>
        <button
          type="button"
          onClick={() => void load()}
          className="rounded-full border border-slate-200 bg-slate-50 px-4 py-2 text-xs font-black uppercase tracking-[0.18em] text-slate-700"
        >
          Recarregar
        </button>
      </div>

      <div className="mt-5 grid gap-5 xl:grid-cols-[1.1fr_0.9fr]">
        <div className="space-y-3">
          <div className="rounded-[1.3rem] border border-slate-100 bg-slate-50 p-4">
            <p className="text-[11px] font-black uppercase tracking-[0.18em] text-slate-500">Status</p>
            <p className="mt-2 text-sm text-slate-700">{status}</p>
          </div>

          <div className="grid gap-3 md:grid-cols-2">
            {fields.map((field) => (
              <label key={field.key} className="rounded-[1.2rem] border border-slate-200 bg-white px-4 py-3">
                <p className="text-[11px] font-black uppercase tracking-[0.18em] text-slate-500">{field.label}</p>
                <input
                  value={formValues[field.key] ?? ''}
                  onChange={(event) => setFormValues((current) => ({ ...current, [field.key]: event.target.value }))}
                  placeholder={field.placeholder ?? `Preencha ${field.label.toLowerCase()}`}
                  className="mt-2 w-full border-none bg-transparent text-sm font-semibold text-slate-900 outline-none"
                />
              </label>
            ))}
          </div>

          <div className="flex flex-wrap gap-2">
            <button
              type="button"
              onClick={() => void createRecord()}
              disabled={busy}
              className="rounded-full bg-slate-950 px-4 py-2 text-xs font-black uppercase tracking-[0.18em] text-white disabled:opacity-50"
            >
              Criar
            </button>
            <button
              type="button"
              onClick={() => void updateRecord()}
              disabled={busy}
              className="rounded-full border border-slate-200 bg-white px-4 py-2 text-xs font-black uppercase tracking-[0.18em] text-slate-800 disabled:opacity-50"
            >
              Editar
            </button>
            <button
              type="button"
              onClick={() => void deleteRecord()}
              disabled={busy}
              className="rounded-full border border-rose-200 bg-rose-50 px-4 py-2 text-xs font-black uppercase tracking-[0.18em] text-rose-700 disabled:opacity-50"
            >
              Excluir
            </button>
            <button
              type="button"
              onClick={resetForm}
              disabled={busy}
              className="rounded-full border border-slate-200 bg-slate-50 px-4 py-2 text-xs font-black uppercase tracking-[0.18em] text-slate-700 disabled:opacity-50"
            >
              Limpar
            </button>
          </div>
        </div>

        <div className="rounded-[1.3rem] border border-slate-200 bg-slate-50 p-4">
          <p className="text-[11px] font-black uppercase tracking-[0.18em] text-slate-500">Registros locais</p>
          <div className="mt-4 space-y-3">
            {records.map((record) => (
              <button
                key={record.id}
                type="button"
                onClick={() => handleSelect(record)}
                className={[
                  'w-full rounded-[1.1rem] border px-4 py-3 text-left transition',
                  selectedId === record.id ? 'border-slate-900 bg-slate-900 text-white' : 'border-slate-200 bg-white text-slate-900',
                ].join(' ')}
              >
                <p className="text-xs font-black uppercase tracking-[0.16em]">{record.id}</p>
                <p className="mt-2 text-sm">{fields.map((field) => stringifyValue(record[field.key])).filter(Boolean).slice(0, 3).join(' · ') || 'Sem resumo'}</p>
              </button>
            ))}
            {records.length === 0 ? <p className="text-sm text-slate-500">Nenhum registro salvo ainda.</p> : null}
          </div>
        </div>
      </div>
    </section>
  );
}
