/**
 * Label manager — create labels with colors, assign to mails.
 */

import React, { useState, useEffect, useCallback } from 'react';
import { useTranslation } from 'react-i18next';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Button } from '@/components/ui/Button';
import { Input } from '@/components/ui/Input';
import { Card } from '@/components/ui/Card';
import { EmptyState } from '@/components/ui/EmptyState';
import { useToast } from '@/components/ui/Toast';
import { ConfirmDialog } from '@/components/ui/ConfirmDialog';
import { Loader2, X } from 'lucide-react';
import {
  fetchLabels,
  createLabel,
  deleteLabel,
  type MailLabel,
} from '@/api/mail';

const PRESET_COLORS = [
  '#ef4444', '#f59e0b', '#10b981', '#3b82f6',
  '#8b5cf6', '#ec4899', '#6366f1', '#64748b',
];

export function LabelManager() {
  const { t } = useTranslation();
  const toast = useToast();
  const [labels, setLabels] = useState<MailLabel[]>([]);
  const [loading, setLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);
  const [showForm, setShowForm] = useState(false);
  const [saving, setSaving] = useState(false);
  const [deleteTarget, setDeleteTarget] = useState<MailLabel | null>(null);

  // ── Label form (RHF + Zod) ──
  const labelSchema = z.object({
    name: z.string().min(1, 'required'),
    color: z.string().optional().default(PRESET_COLORS[0]),
  });
  type LabelFormData = z.infer<typeof labelSchema>;

  const { register: registerLabel, handleSubmit: handleSubmitLabel, reset: resetLabel, watch: watchLabel, setValue: setLabelValue, formState: { errors: labelErrors } } = useForm<LabelFormData>({
    resolver: zodResolver(labelSchema),
    defaultValues: { name: '', color: PRESET_COLORS[0] },
  });

  const colorValue = watchLabel('color');

  const load = useCallback(() => {
    setLoading(true);
    fetchLabels()
      .then((data) => {
        setLabels(data);
        setError(null);
      })
      .catch((err) => {
        setError(err instanceof Error ? err.message : String(err));
      })
      .finally(() => setLoading(false));
  }, []);

  useEffect(() => { load(); }, [load]);

  const handleSave = useCallback(async (data: LabelFormData) => {
    setSaving(true);
    try {
      const label = await createLabel({ name: data.name, color: data.color });
      setLabels((prev) => [...prev, label]);
      toast.success(t('mail.labelCreated'));
      setShowForm(false);
      resetLabel({ name: '', color: PRESET_COLORS[0] });
    } catch (err) {
      toast.error(err instanceof Error ? err.message : String(err));
    } finally {
      setSaving(false);
    }
  }, [toast, t, resetLabel]);

  const handleDelete = useCallback(async () => {
    if (!deleteTarget) return;
    try {
      await deleteLabel(deleteTarget.id);
      setLabels((prev) => prev.filter((l) => l.id !== deleteTarget.id));
      toast.success(t('mail.labelDeleted'));
      setDeleteTarget(null);
    } catch (err) {
      toast.error(err instanceof Error ? err.message : String(err));
    }
  }, [deleteTarget, toast, t]);

  if (loading) {
    return (
      <div className="flex items-center justify-center py-8" data-testid="label-manager-loading">
        <Loader2 className="animate-spin h-5 w-5 text-secondary-400" aria-hidden="true" />
      </div>
    );
  }

  if (error) {
    return (
      <div className="p-4 bg-danger-50 border border-danger-200 rounded-md" role="alert" data-testid="label-manager-error">
        <p className="text-sm text-danger-700">{error}</p>
      </div>
    );
  }

  return (
    <div data-testid="label-manager">
      <div className="flex items-center justify-between mb-4">
        <h3 className="text-lg font-semibold text-secondary-900">{t('mail.labels')}</h3>
        <Button size="sm" onClick={() => setShowForm(!showForm)} data-testid="new-label-btn">{t('mail.newLabel')}</Button>
      </div>

      {showForm && (
        <Card className="mb-4" data-testid="label-form">
          <form onSubmit={handleSubmitLabel(handleSave)} className="space-y-3">
            <Input
              label={t('mail.labelName')}
              {...registerLabel('name')}
              error={labelErrors.name?.message === 'required' ? t('validation.required') : undefined}
              placeholder={t('mail.labelName')}
              required
            />
            <div>
              <label className="block text-sm font-medium text-secondary-700 mb-2">{t('mail.labelColor')}</label>
              <div className="flex flex-wrap gap-2" data-testid="label-color-picker">
                {PRESET_COLORS.map((c) => (
                  <button
                    key={c}
                    type="button"
                    onClick={() => setLabelValue('color', c)}
                    className={`w-8 h-8 rounded-full ${colorValue === c ? 'ring-2 ring-offset-2 ring-primary-500' : ''}`}
                    style={{ backgroundColor: c }}
                    aria-label={c}
                  />
                ))}
              </div>
            </div>
            <div className="flex gap-2">
              <Button type="submit" isLoading={saving} size="sm">{t('common.save')}</Button>
              <Button variant="secondary" size="sm" type="button" onClick={() => setShowForm(false)}>{t('common.cancel')}</Button>
            </div>
          </form>
        </Card>
      )}

      {labels.length === 0 && !showForm ? (
        <EmptyState title={t('mail.noLabels')} description={t('mail.noLabelsDesc')} />
      ) : (
        <div className="flex flex-wrap gap-2" data-testid="label-list">
          {labels.map((label) => (
            <div
              key={label.id}
              className="inline-flex items-center gap-2 px-3 py-1.5 rounded-full text-sm"
              style={{ backgroundColor: label.color, color: '#fff' }}
            >
              <span>{label.name}</span>
              <button
                onClick={() => setDeleteTarget(label)}
                className="hover:opacity-70"
                aria-label={t('common.delete')}
                data-testid={`delete-label-${label.id}`}
                type="button"
              >
                <X className="w-4 h-4" aria-hidden="true" strokeWidth={2} />
              </button>
            </div>
          ))}
        </div>
      )}

      <ConfirmDialog
        open={!!deleteTarget}
        title={t('mail.deleteLabel')}
        message={t('mail.confirmDeleteLabel')}
        confirmLabel={t('common.delete')}
        variant="danger"
        onConfirm={handleDelete}
        onCancel={() => setDeleteTarget(null)}
      />
    </div>
  );
}