import React, { useEffect } from 'react';
import { useTranslation } from 'react-i18next';
import { useForm } from 'react-hook-form';
import { zodResolver } from '@hookform/resolvers/zod';
import { z } from 'zod';
import { Modal } from '@/components/ui/Modal';
import { Input } from '@/components/ui/Input';
import { Select } from '@/components/ui/Select';
import { Button } from '@/components/ui/Button';
import { useToast } from '@/components/ui/Toast';
import {
  type UnifiedContact,
  useCreateUnifiedContact,
  useUpdateUnifiedContact,
} from '@/api/hooks';
import { CustomFieldRenderer } from '@/components/contacts/CustomFieldRenderer';
import { useCustomFields, useUpdateCustomFields } from '@/api/customFields';
import { usePluginStore } from '@/store/pluginStore';

export interface ContactEditModalProps {
  open: boolean;
  onClose: () => void;
  contact?: UnifiedContact | null;
  onSaved?: (id: string) => void;
}

// ── Zod Schema ──

const phoneRegex = /^[+]?[\d\s\-().]{6,20}$/;

const contactSchema = z.object({
  type: z.enum(['company', 'person']),
  name: z.string().optional().default(''),
  firstname: z.string().optional().default(''),
  surname: z.string().optional().default(''),
  code: z.string().optional().default(''),
  email_1: z.string().email('Invalid email').or(z.literal('')).optional().default(''),
  email_2: z.string().email('Invalid email').or(z.literal('')).optional().default(''),
  phone_1: z.string().regex(phoneRegex, 'Invalid phone').or(z.literal('')).optional().default(''),
  phone_2: z.string().regex(phoneRegex, 'Invalid phone').or(z.literal('')).optional().default(''),
  website: z.string().optional().default(''),
  mailing_street: z.string().optional().default(''),
  mailing_number: z.string().optional().default(''),
  mailing_postalcode: z.string().optional().default(''),
  mailing_city: z.string().optional().default(''),
  mailing_country: z.string().optional().default(''),
  vat_code: z.string().optional().default(''),
  fiscal_code: z.string().optional().default(''),
  commerce_code: z.string().optional().default(''),
  bic: z.string().optional().default(''),
  bank_account: z.string().optional().default(''),
  tags: z.string().optional().default(''),
  projectnote: z.string().optional().default(''),
  contact_warning: z.string().optional().default(''),
}).superRefine((data, ctx) => {
  if (data.type === 'company' && !data.name?.trim()) {
    ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Required', path: ['name'] });
  }
  if (data.type === 'person' && !data.firstname?.trim() && !data.surname?.trim()) {
    ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Required', path: ['firstname'] });
    ctx.addIssue({ code: z.ZodIssueCode.custom, message: 'Required', path: ['surname'] });
  }
});

type ContactFormData = z.infer<typeof contactSchema>;

export function ContactEditModal({ open, onClose, contact, onSaved }: ContactEditModalProps) {
  const { t } = useTranslation();
  const toast = useToast();
  const createMutation = useCreateUnifiedContact();
  const updateMutation = useUpdateUnifiedContact();
  const isEdit = !!contact;

  const {
    register,
    handleSubmit,
    reset,
    watch,
    formState: { errors, isSubmitting },
  } = useForm<ContactFormData>({
    resolver: zodResolver(contactSchema),
    defaultValues: {
      type: 'company',
      name: '',
      firstname: '',
      surname: '',
      code: '',
      email_1: '',
      email_2: '',
      phone_1: '',
      phone_2: '',
      website: '',
      mailing_street: '',
      mailing_number: '',
      mailing_postalcode: '',
      mailing_city: '',
      mailing_country: '',
      vat_code: '',
      fiscal_code: '',
      commerce_code: '',
      bic: '',
      bank_account: '',
      tags: '',
      projectnote: '',
      contact_warning: '',
    },
  });

  const currentType = watch('type');

  // Custom fields
  const customFieldDefs = usePluginStore(s => s.getCustomFieldsForEntity('contact'));
  const { data: customFieldsData } = useCustomFields(contact?.id);
  const updateCustomFields = useUpdateCustomFields();
  const [customValues, setCustomValues] = React.useState<Record<string, any>>({});

  React.useEffect(() => {
    if (open && customFieldsData?.fields) {
      const vals: Record<string, any> = {};
      for (const f of customFieldsData.fields) {
        vals[f.name] = f.value ?? f.default_value ?? null;
      }
      setCustomValues(vals);
    }
  }, [open, customFieldsData]);

  const handleCustomFieldChange = (name: string, value: any) => {
    setCustomValues(prev => ({ ...prev, [name]: value }));
  };

  // Reset form when modal opens
  useEffect(() => {
    if (open) {
      reset({
        type: (contact?.type as 'company' | 'person') || 'company',
        name: contact?.name || '',
        firstname: contact?.firstname || '',
        surname: contact?.surname || '',
        code: contact?.code || '',
        email_1: contact?.email_1 || '',
        email_2: contact?.email_2 || '',
        phone_1: contact?.phone_1 || '',
        phone_2: contact?.phone_2 || '',
        website: contact?.website || '',
        mailing_street: contact?.mailing_street || '',
        mailing_number: contact?.mailing_number || '',
        mailing_postalcode: contact?.mailing_postalcode || '',
        mailing_city: contact?.mailing_city || '',
        mailing_country: contact?.mailing_country || '',
        vat_code: contact?.vat_code || '',
        fiscal_code: contact?.fiscal_code || '',
        commerce_code: contact?.commerce_code || '',
        bic: contact?.bic || '',
        bank_account: contact?.bank_account || '',
        tags: contact?.tags || '',
        projectnote: contact?.projectnote || '',
        contact_warning: contact?.contact_warning || '',
      });
    }
  }, [open, contact, reset]);

  const onSubmit = async (formData: ContactFormData) => {
    const data: Partial<UnifiedContact> = {
      type: formData.type,
      name: formData.type === 'company' ? formData.name || null : null,
      firstname: formData.type === 'person' ? formData.firstname || null : null,
      surname: formData.type === 'person' ? formData.surname || null : null,
      code: formData.code || null,
      email_1: formData.email_1 || null,
      email_2: formData.email_2 || null,
      phone_1: formData.phone_1 || null,
      phone_2: formData.phone_2 || null,
      website: formData.website || null,
      mailing_street: formData.mailing_street || null,
      mailing_number: formData.mailing_number || null,
      mailing_postalcode: formData.mailing_postalcode || null,
      mailing_city: formData.mailing_city || null,
      mailing_country: formData.mailing_country || null,
      vat_code: formData.vat_code || null,
      fiscal_code: formData.fiscal_code || null,
      commerce_code: formData.commerce_code || null,
      bic: formData.bic || null,
      bank_account: formData.bank_account || null,
      tags: formData.tags || null,
      projectnote: formData.projectnote || null,
      contact_warning: formData.contact_warning || null,
    };

    try {
      let savedId: string | undefined;
      if (isEdit && contact) {
        await updateMutation.mutateAsync({ id: contact.id, data });
        savedId = contact.id;
        toast.success(t('contacts.updated'));
        onSaved?.(contact.id);
      } else {
        const result = await createMutation.mutateAsync(data) as { id: string };
        savedId = result.id;
        toast.success(t('contacts.created'));
        onSaved?.(result.id);
      }
      // Save custom fields if any definitions exist and we have a contact ID
      if (savedId && customFieldDefs.length > 0 && Object.keys(customValues).length > 0) {
        try {
          await updateCustomFields.mutateAsync({ contactId: savedId, values: customValues });
        } catch (cfErr: any) {
          // Don't fail the whole save if custom fields fail
          console.error('Custom fields save failed:', cfErr);
        }
      }
      onClose();
    } catch (err: any) {
      toast.error(err.message || (isEdit ? t('contacts.updateFailed') : t('contacts.createFailed')));
    }
  };

  return (
    <Modal open={open} onClose={onClose} title={isEdit ? t('contacts.edit') : t('contacts.create')} size="xl" fullScreenMobile>
      <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
        {/* Type */}
        <Select
          label={t('contacts.type')}
          {...register('type')}
          options={[
            { value: 'company', label: t('contacts.companies') },
            { value: 'person', label: t('contacts.persons') },
          ]}
          data-testid="contact-type-select"
        />

        {/* Name fields */}
        {currentType === 'company' ? (
          <Input
            label={t('contacts.name')}
            {...register('name')}
            error={errors.name?.message}
            required
            data-testid="contact-name-input"
            placeholder="TechCorp GmbH"
          />
        ) : (
          <div className="grid grid-cols-2 gap-3">
            <Input
              label={t('contacts.firstName')}
              {...register('firstname')}
              error={errors.firstname?.message}
              data-testid="contact-first-name-input"
            />
            <Input
              label={t('contacts.lastName')}
              {...register('surname')}
              error={errors.surname?.message}
              data-testid="contact-last-name-input"
            />
          </div>
        )}

        {/* Code */}
        <Input label={t('contacts.code')} {...register('code')} placeholder="K-00123" />

        {/* Communication */}
        <div className="border border-secondary-200 rounded-lg p-3">
          <h3 className="text-sm font-semibold text-secondary-700 mb-2">{t('contacts.communication')}</h3>
          <div className="grid grid-cols-2 gap-3">
            <Input label={t('contacts.email') + ' 1'} type="email" {...register('email_1')} error={errors.email_1?.message} />
            <Input label={t('contacts.email') + ' 2'} type="email" {...register('email_2')} error={errors.email_2?.message} />
            <Input label={t('contacts.phone') + ' 1'} {...register('phone_1')} error={errors.phone_1?.message} />
            <Input label={t('contacts.phone') + ' 2'} {...register('phone_2')} error={errors.phone_2?.message} />
            <Input label={t('contacts.website')} {...register('website')} />
          </div>
        </div>

        {/* Mailing Address */}
        <div className="border border-secondary-200 rounded-lg p-3">
          <h3 className="text-sm font-semibold text-secondary-700 mb-2">{t('contacts.mailingAddress')}</h3>
          <div className="grid grid-cols-2 gap-3">
            <Input label={t('address.street')} {...register('mailing_street')} />
            <Input label={t('address.streetNumber')} {...register('mailing_number')} />
            <Input label={t('address.zip')} {...register('mailing_postalcode')} />
            <Input label={t('address.city')} {...register('mailing_city')} />
            <Input label={t('address.country')} {...register('mailing_country')} />
          </div>
        </div>

        {/* Financial */}
        <div className="border border-secondary-200 rounded-lg p-3">
          <h3 className="text-sm font-semibold text-secondary-700 mb-2">{t('contacts.financial')}</h3>
          <div className="grid grid-cols-2 gap-3">
            <Input label={t('contacts.vatCode')} {...register('vat_code')} />
            <Input label={t('contacts.fiscalCode')} {...register('fiscal_code')} />
            <Input label={t('contacts.commerceCode')} {...register('commerce_code')} />
            <Input label={t('contacts.bic')} {...register('bic')} />
            <Input label={t('contacts.bankAccount')} {...register('bank_account')} />
          </div>
        </div>

        {/* Notes */}
        <div className="border border-secondary-200 rounded-lg p-3">
          <h3 className="text-sm font-semibold text-secondary-700 mb-2">{t('contacts.notes')}</h3>
          <div className="space-y-3">
            <Input label={t('contacts.tags')} {...register('tags')} placeholder="tag1, tag2" />
            <div>
              <label className="block text-sm font-medium text-secondary-700 mb-1">{t('contacts.projectnote')}</label>
              <textarea
                {...register('projectnote')}
                className="w-full px-3 py-2 text-sm rounded-md border border-secondary-300 focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-20"
              />
            </div>
            <div>
              <label className="block text-sm font-medium text-secondary-700 mb-1">{t('contacts.contactWarning')}</label>
              <textarea
                {...register('contact_warning')}
                className="w-full px-3 py-2 text-sm rounded-md border border-secondary-300 focus:outline-none focus:ring-2 focus:ring-primary-500 min-h-20"
              />
            </div>
          </div>
        </div>

        {/* Custom Fields */}
        {customFieldDefs.length > 0 && (
          <div className="border border-secondary-200 rounded-lg p-3">
            <h3 className="text-sm font-semibold text-secondary-700 mb-2">{t('contacts.customFields')}</h3>
            <CustomFieldRenderer
              fields={customFieldsData?.fields || customFieldDefs.map(d => ({ ...d, value: d.default_value, plugin: '' }))}
              mode="edit"
              values={customValues}
              onChange={handleCustomFieldChange}
            />
          </div>
        )}

        {/* Actions */}
        <div className="flex justify-end gap-2 pt-2">
          <Button variant="secondary" onClick={onClose}>{t('common.cancel')}</Button>
          <Button type="submit" isLoading={isSubmitting || createMutation.isPending || updateMutation.isPending} data-testid="contact-submit-btn">
            {isEdit ? t('common.save') : t('common.create')}
          </Button>
        </div>
      </form>
    </Modal>
  );
}
