import { useState, useEffect, useRef, useCallback } from 'react';
import { Modal } from '../../components/Modal';
import { useCreateDeal, useUpdateDeal, usePipelines, useDealTypes, useSetCustomFieldValues } from '../hooks';
import { contactsApi, companiesApi } from '../api';
import { CustomFieldsForm } from '../CustomFieldsForm';
import type { Deal, DealStatus, LostReason, Contact, Company, CustomFieldValue } from '../types';
import { LOST_REASON_LABELS } from '../types';

interface DealFormModalProps {
  isOpen: boolean;
  onClose: () => void;
  deal?: Deal | null;
  onSuccess: () => void;
}

const STATUS_OPTIONS: { value: DealStatus; label: string }[] = [
  { value: 'OPEN', label: 'Offen' },
  { value: 'WON', label: 'Gewonnen' },
  { value: 'LOST', label: 'Verloren' },
];

const labelStyle: React.CSSProperties = {
  fontSize: '0.875rem',
  fontWeight: 500,
  color: 'var(--color-text)',
  marginBottom: '0.25rem',
  display: 'block',
};

const inputStyle: React.CSSProperties = {
  width: '100%',
  padding: '0.625rem 0.75rem',
  border: '1px solid var(--color-border)',
  borderRadius: 'var(--radius-sm)',
  fontSize: '0.9375rem',
  outline: 'none',
  boxSizing: 'border-box',
  background: 'var(--color-bg-card)',
  color: 'var(--color-text)',
};

const rowStyle: React.CSSProperties = {
  display: 'grid',
  gridTemplateColumns: '1fr 1fr',
  gap: '0.75rem',
};

export function DealFormModal({
  isOpen,
  onClose,
  deal,
  onSuccess,
}: DealFormModalProps) {
  const isEditMode = !!deal;
  const createMutation = useCreateDeal();
  const updateMutation = useUpdateDeal();
  const setCustomFieldValues = useSetCustomFieldValues();
  const mutation = isEditMode ? updateMutation : createMutation;

  const customFieldValuesRef = useRef<Record<string, string | number | boolean | string[] | null>>({});
  const customFields: CustomFieldValue[] = deal?.customFields ?? [];
  const handleCustomFieldsChange = useCallback(
    (values: Record<string, string | number | boolean | string[] | null>) => {
      customFieldValuesRef.current = values;
    },
    [],
  );

  const { data: pipelinesData } = usePipelines();
  const pipelines = pipelinesData?.data ?? [];
  const { data: dealTypesData } = useDealTypes();
  const dealTypes = dealTypesData?.data ?? [];

  const [error, setError] = useState('');
  const [title, setTitle] = useState('');
  const [pipelineId, setPipelineId] = useState('');
  const [stageId, setStageId] = useState('');
  const [status, setStatus] = useState<DealStatus>('OPEN');
  const [value, setValue] = useState('');
  const [currency, setCurrency] = useState('EUR');
  const [expectedCloseDate, setExpectedCloseDate] = useState('');
  const [notes, setNotes] = useState('');
  const [lostReason, setLostReason] = useState<LostReason | ''>('');
  const [lostReasonText, setLostReasonText] = useState('');
  const [dealTypeId, setDealTypeId] = useState('');

  // Kontakt-Suche
  const [contactSearch, setContactSearch] = useState('');
  const [contactResults, setContactResults] = useState<Contact[]>([]);
  const [selectedContact, setSelectedContact] = useState<{
    id: string;
    name: string;
  } | null>(null);
  const [showContactDropdown, setShowContactDropdown] = useState(false);
  const contactRef = useRef<HTMLDivElement>(null);
  const searchTimeoutRef = useRef<ReturnType<typeof setTimeout>>();

  // Unternehmen-Suche
  const [companySearch, setCompanySearch] = useState('');
  const [companyResults, setCompanyResults] = useState<Company[]>([]);
  const [selectedCompany, setSelectedCompany] = useState<{
    id: string;
    name: string;
  } | null>(null);
  const [showCompanyDropdown, setShowCompanyDropdown] = useState(false);
  const companyRef = useRef<HTMLDivElement>(null);
  const companySearchTimeout = useRef<ReturnType<typeof setTimeout>>();

  // Stages der gewaehlten Pipeline
  const selectedPipeline = pipelines.find((p) => p.id === pipelineId);
  const stages = selectedPipeline?.stages
    ? [...selectedPipeline.stages].sort((a, b) => a.sortOrder - b.sortOrder)
    : [];

  // Click-Outside für Kontakt- und Unternehmen-Dropdown
  useEffect(() => {
    function handleClick(e: MouseEvent) {
      if (
        contactRef.current &&
        !contactRef.current.contains(e.target as Node)
      ) {
        setShowContactDropdown(false);
      }
      if (
        companyRef.current &&
        !companyRef.current.contains(e.target as Node)
      ) {
        setShowCompanyDropdown(false);
      }
    }
    document.addEventListener('mousedown', handleClick);
    return () => document.removeEventListener('mousedown', handleClick);
  }, []);

  // Kontakt suchen (debounced)
  useEffect(() => {
    if (searchTimeoutRef.current) clearTimeout(searchTimeoutRef.current);
    if (!contactSearch || contactSearch.length < 2) {
      setContactResults([]);
      return;
    }
    searchTimeoutRef.current = setTimeout(async () => {
      try {
        const res = await contactsApi.list({
          search: contactSearch,
          pageSize: 8,
        });
        setContactResults(res.data);
        setShowContactDropdown(true);
      } catch {
        setContactResults([]);
      }
    }, 300);
    return () => {
      if (searchTimeoutRef.current) clearTimeout(searchTimeoutRef.current);
    };
  }, [contactSearch]);

  // Unternehmen suchen (debounced)
  useEffect(() => {
    if (companySearchTimeout.current) clearTimeout(companySearchTimeout.current);
    if (!companySearch || companySearch.length < 2) {
      setCompanyResults([]);
      return;
    }
    companySearchTimeout.current = setTimeout(async () => {
      try {
        const res = await companiesApi.list({
          search: companySearch,
          pageSize: 8,
        });
        setCompanyResults(res.data);
        setShowCompanyDropdown(true);
      } catch {
        setCompanyResults([]);
      }
    }, 300);
    return () => {
      if (companySearchTimeout.current) clearTimeout(companySearchTimeout.current);
    };
  }, [companySearch]);

  useEffect(() => {
    if (isOpen) {
      setError('');
      if (deal) {
        setTitle(deal.title);
        setPipelineId(deal.pipelineId);
        setStageId(deal.stageId);
        setStatus(deal.status);
        setValue(deal.value ? String(parseFloat(deal.value)) : '');
        setCurrency(deal.currency ?? 'EUR');
        setExpectedCloseDate(
          deal.expectedCloseDate
            ? deal.expectedCloseDate.slice(0, 10)
            : '',
        );
        setNotes(deal.notes ?? '');
        setLostReason((deal.lostReason as LostReason) ?? '');
        setLostReasonText(deal.lostReasonText ?? '');
        setDealTypeId(deal.dealTypeId ?? '');
        if (deal.contact) {
          const { id, firstName, lastName, companyName } = deal.contact;
          const name =
            companyName ||
            [firstName, lastName].filter(Boolean).join(' ') ||
            'Kontakt';
          setSelectedContact({ id, name });
          setContactSearch(name);
        } else {
          setSelectedContact(null);
          setContactSearch('');
        }
        if (deal.company) {
          setSelectedCompany({ id: deal.company.id, name: deal.company.name });
          setCompanySearch(deal.company.name);
        } else {
          setSelectedCompany(null);
          setCompanySearch('');
        }
      } else {
        setTitle('');
        setPipelineId(pipelines.find((p) => p.isDefault)?.id ?? pipelines[0]?.id ?? '');
        setStageId('');
        setStatus('OPEN');
        setValue('');
        setCurrency('EUR');
        setExpectedCloseDate('');
        setNotes('');
        setLostReason('');
        setLostReasonText('');
        setDealTypeId('');
        setSelectedContact(null);
        setContactSearch('');
        setSelectedCompany(null);
        setCompanySearch('');
      }
      setContactResults([]);
      setShowContactDropdown(false);
      setCompanyResults([]);
      setShowCompanyDropdown(false);
    }
  }, [isOpen, deal, pipelines]);

  // Wenn Pipeline wechselt, erste Stage auswaehlen
  useEffect(() => {
    if (!isEditMode && stages.length > 0 && !stages.find((s) => s.id === stageId)) {
      setStageId(stages[0].id);
    }
  }, [pipelineId, stages, stageId, isEditMode]);

  const handleSubmit = (e: React.FormEvent) => {
    e.preventDefault();
    setError('');

    if (!title.trim()) {
      setError('Titel ist ein Pflichtfeld');
      return;
    }
    if (!pipelineId) {
      setError('Pipeline auswählen');
      return;
    }
    if (!stageId) {
      setError('Stage auswählen');
      return;
    }
    if (status === 'LOST' && !lostReason) {
      setError('Bitte einen Grund fuer den Verlust angeben');
      return;
    }

    const payload = {
      title: title.trim(),
      pipelineId,
      stageId,
      status,
      ...(selectedContact ? { contactId: selectedContact.id } : {}),
      ...(selectedCompany ? { companyId: selectedCompany.id } : {}),
      ...(value ? { value: parseFloat(value) } : {}),
      currency,
      ...(expectedCloseDate ? { expectedCloseDate: new Date(expectedCloseDate).toISOString() } : {}),
      ...(notes ? { notes } : {}),
      ...(status === 'LOST' && lostReason ? { lostReason } : {}),
      ...(status === 'LOST' && lostReasonText ? { lostReasonText } : {}),
      ...(dealTypeId ? { dealTypeId } : {}),
    };

    const saveCustomFields = (entityId: string) => {
      const vals = customFieldValuesRef.current;
      const entries = Object.entries(vals);
      if (entries.length === 0) return;
      setCustomFieldValues.mutate({
        entityId,
        data: {
          values: entries.map(([fieldDefId, value]) => ({ fieldDefId, value })),
        },
      });
    };

    if (isEditMode && deal) {
      updateMutation.mutate(
        { id: deal.id, data: payload },
        {
          onSuccess: () => {
            saveCustomFields(deal.id);
            onSuccess();
          },
          onError: (err: unknown) => {
            const msg =
              (err as { response?: { data?: { error?: { message?: string } } } })
                ?.response?.data?.error?.message ?? 'Fehler beim Speichern';
            setError(msg);
          },
        },
      );
    } else {
      createMutation.mutate(payload, {
        onSuccess: (res) => {
          if (res?.data?.id) saveCustomFields(res.data.id);
          onSuccess();
        },
        onError: (err: unknown) => {
          const msg =
            (err as { response?: { data?: { error?: { message?: string } } } })
              ?.response?.data?.error?.message ?? 'Fehler beim Anlegen';
          setError(msg);
        },
      });
    }
  };

  return (
    <Modal
      isOpen={isOpen}
      onClose={onClose}
      title={isEditMode ? 'Vorgang bearbeiten' : 'Neuer Vorgang'}
      maxWidth="600px"
    >
      <form onSubmit={handleSubmit}>
        {error && (
          <div
            style={{
              padding: '0.75rem',
              background: '#fef2f2',
              border: '1px solid #fecaca',
              borderRadius: 'var(--radius-sm)',
              color: 'var(--color-error)',
              fontSize: '0.875rem',
              marginBottom: '1rem',
            }}
          >
            {error}
          </div>
        )}

        {/* Titel */}
        <div style={{ marginBottom: '1rem' }}>
          <label style={labelStyle}>Titel *</label>
          <input
            style={inputStyle}
            value={title}
            onChange={(e) => setTitle(e.target.value)}
            placeholder="Vorgangs-Titel"
            required
          />
        </div>

        {/* Pipeline leer – Hinweis */}
        {pipelines.length === 0 && (
          <div
            style={{
              padding: '0.75rem',
              background: 'var(--color-warning-bg, #fffbeb)',
              border: '1px solid var(--color-warning-border, #fde68a)',
              borderRadius: 'var(--radius-sm)',
              color: 'var(--color-warning, #92400e)',
              fontSize: '0.875rem',
              marginBottom: '1rem',
            }}
          >
            ⚠️ Keine Pipelines vorhanden. Bitte zuerst unter{' '}
            <a href="/crm/settings" style={{ color: 'inherit', fontWeight: 600 }}>
              CRM&nbsp;Einstellungen&nbsp;→&nbsp;Pipelines
            </a>{' '}
            eine Pipeline anlegen.
          </div>
        )}

        {/* Pipeline + Stage */}
        <div style={{ ...rowStyle, marginBottom: '1rem' }}>
          <div>
            <label style={labelStyle}>Pipeline *</label>
            <select
              value={pipelineId}
              onChange={(e) => setPipelineId(e.target.value)}
              style={{ ...inputStyle, cursor: 'pointer' }}
            >
              <option value="">Pipeline wählen</option>
              {pipelines
                .filter((p) => p.isActive)
                .map((p) => (
                  <option key={p.id} value={p.id}>
                    {p.name}
                    {p.isDefault ? ' (Standard)' : ''}
                  </option>
                ))}
            </select>
          </div>
          <div>
            <label style={labelStyle}>Stage *</label>
            <select
              value={stageId}
              onChange={(e) => setStageId(e.target.value)}
              style={{ ...inputStyle, cursor: 'pointer' }}
              disabled={stages.length === 0}
            >
              <option value="">Stage wählen</option>
              {stages.map((s) => (
                <option key={s.id} value={s.id}>
                  {s.name}
                </option>
              ))}
            </select>
          </div>
        </div>

        {/* Vorgangsart */}
        <div style={{ marginBottom: '1rem' }}>
          <label style={labelStyle}>Vorgangsart</label>
          <select
            value={dealTypeId}
            onChange={(e) => setDealTypeId(e.target.value)}
            style={{ ...inputStyle, cursor: 'pointer' }}
          >
            <option value="">— Keine —</option>
            {dealTypes.map((dt) => (
              <option key={dt.id} value={dt.id}>
                {dt.name}
              </option>
            ))}
          </select>
          {dealTypes.length === 0 && (
            <p style={{ fontSize: '0.8125rem', color: 'var(--color-text-muted)', marginTop: '0.25rem' }}>
              Keine Vorgangsarten konfiguriert.{' '}
              <a href="/crm/settings" style={{ color: 'var(--color-primary)' }}>
                In CRM Einstellungen anlegen
              </a>
            </p>
          )}
        </div>

        {/* Kontakt-Suche */}
        <div style={{ marginBottom: '1rem', position: 'relative' }} ref={contactRef}>
          <label style={labelStyle}>Kontakt</label>
          <input
            style={inputStyle}
            value={contactSearch}
            onChange={(e) => {
              setContactSearch(e.target.value);
              if (selectedContact) setSelectedContact(null);
            }}
            onFocus={() => {
              if (contactResults.length > 0) setShowContactDropdown(true);
            }}
            placeholder="Kontakt suchen..."
          />
          {selectedContact && (
            <button
              type="button"
              onClick={() => {
                setSelectedContact(null);
                setContactSearch('');
              }}
              style={{
                position: 'absolute',
                right: 8,
                top: 30,
                background: 'none',
                border: 'none',
                color: 'var(--color-text-muted)',
                cursor: 'pointer',
                fontSize: '1rem',
              }}
            >
              ×
            </button>
          )}
          {showContactDropdown && contactResults.length > 0 && (
            <div
              style={{
                position: 'absolute',
                top: '100%',
                left: 0,
                right: 0,
                background: 'var(--color-bg-card)',
                border: '1px solid var(--color-border)',
                borderRadius: 'var(--radius-sm)',
                boxShadow: 'var(--shadow-md)',
                zIndex: 10,
                maxHeight: 200,
                overflowY: 'auto',
              }}
            >
              {contactResults.map((c) => {
                const name =
                  c.type === 'ORGANIZATION'
                    ? c.companyName
                    : [c.firstName, c.lastName].filter(Boolean).join(' ');
                return (
                  <div
                    key={c.id}
                    onClick={() => {
                      setSelectedContact({ id: c.id, name: name ?? '' });
                      setContactSearch(name ?? '');
                      setShowContactDropdown(false);
                    }}
                    style={{
                      padding: '0.5rem 0.75rem',
                      cursor: 'pointer',
                      fontSize: '0.875rem',
                      borderBottom: '1px solid var(--color-border)',
                    }}
                    onMouseEnter={(e) =>
                      ((e.target as HTMLDivElement).style.background =
                        'var(--color-bg)')
                    }
                    onMouseLeave={(e) =>
                      ((e.target as HTMLDivElement).style.background =
                        'transparent')
                    }
                  >
                    {name}
                    {c.email && (
                      <span
                        style={{
                          color: 'var(--color-text-muted)',
                          marginLeft: '0.5rem',
                          fontSize: '0.8125rem',
                        }}
                      >
                        {c.email}
                      </span>
                    )}
                  </div>
                );
              })}
            </div>
          )}
        </div>

        {/* Unternehmen-Suche */}
        <div style={{ marginBottom: '1rem', position: 'relative' }} ref={companyRef}>
          <label style={labelStyle}>Unternehmen</label>
          <input
            style={inputStyle}
            value={companySearch}
            onChange={(e) => {
              setCompanySearch(e.target.value);
              if (selectedCompany) setSelectedCompany(null);
            }}
            onFocus={() => {
              if (companyResults.length > 0) setShowCompanyDropdown(true);
            }}
            placeholder="Unternehmen suchen..."
          />
          {selectedCompany && (
            <button
              type="button"
              onClick={() => {
                setSelectedCompany(null);
                setCompanySearch('');
              }}
              style={{
                position: 'absolute',
                right: 8,
                top: 30,
                background: 'none',
                border: 'none',
                color: 'var(--color-text-muted)',
                cursor: 'pointer',
                fontSize: '1rem',
              }}
            >
              ×
            </button>
          )}
          {showCompanyDropdown && companyResults.length > 0 && (
            <div
              style={{
                position: 'absolute',
                top: '100%',
                left: 0,
                right: 0,
                background: 'var(--color-bg-card)',
                border: '1px solid var(--color-border)',
                borderRadius: 'var(--radius-sm)',
                boxShadow: 'var(--shadow-md)',
                zIndex: 10,
                maxHeight: 200,
                overflowY: 'auto',
              }}
            >
              {companyResults.map((comp) => (
                <div
                  key={comp.id}
                  onClick={() => {
                    setSelectedCompany({ id: comp.id, name: comp.name });
                    setCompanySearch(comp.name);
                    setShowCompanyDropdown(false);
                  }}
                  style={{
                    padding: '0.5rem 0.75rem',
                    cursor: 'pointer',
                    fontSize: '0.875rem',
                    borderBottom: '1px solid var(--color-border)',
                  }}
                  onMouseEnter={(e) =>
                    ((e.target as HTMLDivElement).style.background =
                      'var(--color-bg)')
                  }
                  onMouseLeave={(e) =>
                    ((e.target as HTMLDivElement).style.background =
                      'transparent')
                  }
                >
                  {comp.name}
                  {comp.industry && (
                    <span
                      style={{
                        color: 'var(--color-text-muted)',
                        marginLeft: '0.5rem',
                        fontSize: '0.8125rem',
                      }}
                    >
                      {comp.industry}
                    </span>
                  )}
                </div>
              ))}
            </div>
          )}
        </div>

        {/* Wert + Währung */}
        <div style={{ ...rowStyle, marginBottom: '1rem' }}>
          <div>
            <label style={labelStyle}>Wert</label>
            <input
              type="number"
              step="0.01"
              min="0"
              style={inputStyle}
              value={value}
              onChange={(e) => setValue(e.target.value)}
              placeholder="0.00"
            />
          </div>
          <div>
            <label style={labelStyle}>Währung</label>
            <input
              style={inputStyle}
              value={currency}
              onChange={(e) => setCurrency(e.target.value)}
              maxLength={3}
              placeholder="EUR"
            />
          </div>
        </div>

        {/* Status + Erw. Abschluss */}
        <div style={{ ...rowStyle, marginBottom: '1rem' }}>
          <div>
            <label style={labelStyle}>Status</label>
            <select
              value={status}
              onChange={(e) => setStatus(e.target.value as DealStatus)}
              style={{ ...inputStyle, cursor: 'pointer' }}
            >
              {STATUS_OPTIONS.map((o) => (
                <option key={o.value} value={o.value}>
                  {o.label}
                </option>
              ))}
            </select>
          </div>
          <div>
            <label style={labelStyle}>Erw. Abschluss</label>
            <input
              type="date"
              style={inputStyle}
              value={expectedCloseDate}
              onChange={(e) => setExpectedCloseDate(e.target.value)}
            />
          </div>
        </div>

        {/* Lost-Reason (nur bei Status LOST) */}
        {status === 'LOST' && (
          <>
            <div style={{ marginBottom: '1rem' }}>
              <label style={labelStyle}>Verlustgrund *</label>
              <select
                value={lostReason}
                onChange={(e) => setLostReason(e.target.value as LostReason)}
                style={{ ...inputStyle, cursor: 'pointer', borderColor: !lostReason ? 'var(--color-error)' : undefined }}
              >
                <option value="">-- Bitte waehlen --</option>
                {Object.entries(LOST_REASON_LABELS).map(([val, label]) => (
                  <option key={val} value={val}>{label}</option>
                ))}
              </select>
            </div>
            <div style={{ marginBottom: '1rem' }}>
              <label style={labelStyle}>Bemerkung zum Verlust</label>
              <textarea
                style={{ ...inputStyle, minHeight: 50, resize: 'vertical' }}
                value={lostReasonText}
                onChange={(e) => setLostReasonText(e.target.value)}
                placeholder="Optionale Details..."
              />
            </div>
          </>
        )}

        {/* Notizen */}
        <div style={{ marginBottom: '1rem' }}>
          <label style={labelStyle}>Notizen</label>
          <textarea
            style={{ ...inputStyle, minHeight: 60, resize: 'vertical' }}
            value={notes}
            onChange={(e) => setNotes(e.target.value)}
          />
        </div>

        {/* Custom Fields */}
        {customFields.length > 0 && (
          <div style={{ marginBottom: '1rem' }}>
            <CustomFieldsForm
              fields={customFields}
              onChange={handleCustomFieldsChange}
            />
          </div>
        )}

        {/* Buttons */}
        <div
          style={{
            display: 'flex',
            justifyContent: 'flex-end',
            gap: '0.75rem',
          }}
        >
          <button
            type="button"
            onClick={onClose}
            disabled={mutation.isPending}
            style={{
              padding: '0.5rem 1rem',
              background: 'transparent',
              border: '1px solid var(--color-border)',
              borderRadius: 'var(--radius-sm)',
              fontSize: '0.875rem',
              cursor: 'pointer',
              color: 'var(--color-text-secondary)',
            }}
          >
            Abbrechen
          </button>
          <button
            type="submit"
            disabled={mutation.isPending}
            style={{
              padding: '0.5rem 1rem',
              background: 'var(--color-primary)',
              color: 'white',
              border: 'none',
              borderRadius: 'var(--radius-sm)',
              fontSize: '0.875rem',
              fontWeight: 600,
              cursor: mutation.isPending ? 'wait' : 'pointer',
              opacity: mutation.isPending ? 0.7 : 1,
            }}
          >
            {mutation.isPending
              ? 'Speichern...'
              : isEditMode
                ? 'Speichern'
                : 'Anlegen'}
          </button>
        </div>
      </form>
    </Modal>
  );
}
