'use client';

import { useRef, useState } from 'react';
import * as XLSX from 'xlsx';
import { X, Upload, Download, AlertCircle, CheckCircle2, XCircle } from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Label } from '@/components/ui/label';
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select';
import { toast } from '@/lib/toast';
import { handleApiError } from '@/lib/error-handler';
import { useTranslation } from '@/hooks/useTranslation';
import {
  previewWorkCityImport,
  commitWorkCityImport,
  type WorkCityImportRow,
  type WorkCityPreviewResult,
  type WorkCityApprovalAction,
} from '@/services/api/organization';
import { colors, typography } from '@/styles/theme';

interface Props {
  isOpen: boolean;
  onClose: () => void;
  onSuccess?: () => void;
}

type ApprovalMap = Record<string, { action: WorkCityApprovalAction; targetCity?: string }>;

const HEADER_HINTS = ['email', '邮箱', 'mail', 'workcity', 'work_city', '工作地', '城市', 'city'];

export default function BatchImportWorkCityDialog({ isOpen, onClose, onSuccess }: Props) {
  const { t } = useTranslation();
  const i18n = t.organization.workCityImport;

  const [rows, setRows] = useState<WorkCityImportRow[]>([]);
  const [fileName, setFileName] = useState<string | null>(null);
  const [preview, setPreview] = useState<WorkCityPreviewResult | null>(null);
  const [approvals, setApprovals] = useState<ApprovalMap>({});
  const [previewing, setPreviewing] = useState(false);
  const [committing, setCommitting] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  if (!isOpen) return null;

  const reset = () => {
    setRows([]);
    setFileName(null);
    setPreview(null);
    setApprovals({});
    if (fileInputRef.current) fileInputRef.current.value = '';
  };

  const handleClose = () => {
    reset();
    onClose();
  };

  const handleDownloadTemplate = () => {
    const template = [
      { Email: 'alice@example.com', 'Work City': 'Beijing' },
      { Email: 'bob@example.com', 'Work City': 'Shanghai' },
    ];
    const wb = XLSX.utils.book_new();
    const ws = XLSX.utils.json_to_sheet(template);
    ws['!cols'] = [{ wch: 32 }, { wch: 24 }];
    XLSX.utils.book_append_sheet(wb, ws, 'WorkCity');
    XLSX.writeFile(wb, 'work-city-import-template.xlsx');
  };

  const handleFileChange = async (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (!file) return;
    setFileName(file.name);
    setPreview(null);
    setApprovals({});

    try {
      const buf = await file.arrayBuffer();
      const wb = XLSX.read(buf, { type: 'array' });
      const ws = wb.Sheets[wb.SheetNames[0]];
      const aoa = XLSX.utils.sheet_to_json<any[]>(ws, { header: 1, defval: '' });

      const parsed: WorkCityImportRow[] = [];
      aoa.forEach((row, idx) => {
        const a = String(row?.[0] ?? '').trim();
        const b = String(row?.[1] ?? '').trim();
        if (!a && !b) return;
        if (idx === 0 && isHeaderRow(a, b)) return;
        if (!a || !b) return;
        parsed.push({ email: a, workCity: b });
      });

      if (parsed.length === 0) {
        toast.error(i18n.emptyFile);
        setRows([]);
        return;
      }
      setRows(parsed);
      toast.success(i18n.rowsParsed.replace('{count}', String(parsed.length)));
    } catch (err) {
      console.error('parse xlsx failed:', err);
      toast.error(i18n.parseFailed);
      setRows([]);
    }
  };

  const isHeaderRow = (a: string, b: string) => {
    const lower = (a + ' ' + b).toLowerCase();
    return HEADER_HINTS.some((hint) => lower.includes(hint));
  };

  const handlePreview = async () => {
    if (rows.length === 0) return;
    try {
      setPreviewing(true);
      const result = await previewWorkCityImport(rows);
      setPreview(result);
      const init: ApprovalMap = {};
      result.categorized.similar.forEach((c) => {
        init[c.city] = { action: 'replace', targetCity: c.similarTo };
      });
      result.categorized.new.forEach((c) => {
        init[c.city] = { action: 'use' };
      });
      setApprovals(init);
    } catch (err: any) {
      handleApiError(err, t.locale, { prefix: i18n.previewFailed });
    } finally {
      setPreviewing(false);
    }
  };

  const handleCommit = async () => {
    if (!preview) return;
    try {
      setCommitting(true);
      const result = await commitWorkCityImport(rows, approvals);
      toast.success(
        i18n.commitSuccess
          .replace('{created}', String(result.created))
          .replace('{updated}', String(result.updated))
          .replace('{skipped}', String(result.skipped)),
      );
      reset();
      onSuccess?.();
      onClose();
    } catch (err: any) {
      handleApiError(err, t.locale, { prefix: i18n.commitFailed });
    } finally {
      setCommitting(false);
    }
  };

  const summary = preview
    ? i18n.summary
        .replace('{total}', String(preview.total))
        .replace('{cities}', String(preview.uniqueCitiesInFile))
    : '';

  const setApproval = (city: string, patch: Partial<ApprovalMap[string]>) => {
    setApprovals((prev) => {
      const base = prev[city] || { action: 'use' };
      return { ...prev, [city]: { ...base, ...patch } };
    });
  };

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/40" data-testid="work-city-import-dialog">
      <div
        className="bg-white w-full max-w-3xl max-h-[90vh] rounded-lg shadow-lg flex flex-col"
        style={{ border: `1px solid ${colors.border}` }}
      >
        <div className="flex items-center justify-between px-6 h-12 border-b" style={{ borderColor: colors.border }}>
          <h2 className={typography.h4}>{i18n.title}</h2>
          <button onClick={handleClose} aria-label={i18n.cancel} className="hover:opacity-70">
            <X className="w-5 h-5" />
          </button>
        </div>

        <div className="px-6 py-4 overflow-y-auto flex-1 space-y-4">
          <p className={typography.body} style={{ color: colors.textSecondary }}>
            {i18n.description}
          </p>
          <div
            className="p-3 rounded"
            style={{ backgroundColor: colors.bgSecondary, border: `1px solid ${colors.border}` }}
          >
            <p className={typography.caption} style={{ color: colors.textTertiary }}>
              {i18n.templateHint}
            </p>
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={handleDownloadTemplate}
              className="mt-2 flex items-center gap-2"
            >
              <Download className="w-4 h-4" />
              {i18n.downloadTemplate}
            </Button>
          </div>

          <div className="flex items-center gap-3">
            <input
              ref={fileInputRef}
              type="file"
              accept=".xlsx,.xls"
              onChange={handleFileChange}
              className="hidden"
              data-testid="work-city-file-input"
            />
            <Button
              type="button"
              variant="outline"
              onClick={() => fileInputRef.current?.click()}
              className="flex items-center gap-2"
            >
              <Upload className="w-4 h-4" />
              {fileName ? i18n.reselectFile : i18n.selectFile}
            </Button>
            {fileName && (
              <span className={typography.bodySecondary} style={{ color: colors.textSecondary }}>
                {fileName} · {i18n.rowsParsed.replace('{count}', String(rows.length))}
              </span>
            )}
            {rows.length > 0 && (
              <Button
                type="button"
                onClick={handlePreview}
                disabled={previewing}
                className="ml-auto"
                style={{ backgroundColor: colors.primary }}
              >
                {previewing ? i18n.previewing : i18n.preview}
              </Button>
            )}
          </div>

          {preview && (
            <div className="space-y-4" data-testid="work-city-preview">
              <p className={typography.bodySecondary} style={{ color: colors.textSecondary }}>
                {summary}
              </p>

              {preview.categorized.exact.length > 0 && (
                <Section
                  icon={<CheckCircle2 className="w-4 h-4" style={{ color: colors.success }} />}
                  title={i18n.categoryExactTitle}
                  hint={i18n.categoryExactHint}
                >
                  <ul className="space-y-1">
                    {preview.categorized.exact.map((c) => (
                      <li key={c.city} className="flex justify-between text-sm">
                        <span>{c.city}</span>
                        <span style={{ color: colors.textTertiary }}>
                          {i18n.rowsCount.replace('{count}', String(c.rowCount))}
                        </span>
                      </li>
                    ))}
                  </ul>
                </Section>
              )}

              {preview.categorized.similar.length > 0 && (
                <Section
                  icon={<AlertCircle className="w-4 h-4" style={{ color: colors.warning }} />}
                  title={i18n.categorySimilarTitle}
                  hint={i18n.categorySimilarHint}
                >
                  <ul className="space-y-2">
                    {preview.categorized.similar.map((c) => (
                      <li key={c.city} className="flex items-center gap-3 text-sm">
                        <span className="flex-1">
                          <span style={{ fontWeight: 500 }}>{c.city}</span>
                          <span className="ml-2" style={{ color: colors.textTertiary }}>
                            {i18n.similarTo.replace('{city}', c.similarTo)} ·{' '}
                            {i18n.distanceHint.replace('{distance}', String(c.distance))} ·{' '}
                            {i18n.rowsCount.replace('{count}', String(c.rowCount))}
                          </span>
                        </span>
                        <Select
                          value={approvals[c.city]?.action || 'replace'}
                          onValueChange={(v) =>
                            setApproval(c.city, {
                              action: v as WorkCityApprovalAction,
                              targetCity: v === 'replace' ? c.similarTo : undefined,
                            })
                          }
                        >
                          <SelectTrigger className="w-[180px] h-8">
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="replace">
                              {i18n.actionReplace.replace('{city}', c.similarTo)}
                            </SelectItem>
                            <SelectItem value="use">{i18n.actionUse}</SelectItem>
                            <SelectItem value="skip">{i18n.actionSkip}</SelectItem>
                          </SelectContent>
                        </Select>
                      </li>
                    ))}
                  </ul>
                </Section>
              )}

              {preview.categorized.new.length > 0 && (
                <Section
                  icon={<span style={{ color: colors.primary }}>🔵</span>}
                  title={i18n.categoryNewTitle}
                  hint={i18n.categoryNewHint}
                >
                  <ul className="space-y-2">
                    {preview.categorized.new.map((c) => (
                      <li key={c.city} className="flex items-center gap-3 text-sm">
                        <span className="flex-1">
                          <span style={{ fontWeight: 500 }}>{c.city}</span>
                          <span className="ml-2" style={{ color: colors.textTertiary }}>
                            {i18n.rowsCount.replace('{count}', String(c.rowCount))}
                          </span>
                        </span>
                        <Select
                          value={approvals[c.city]?.action || 'use'}
                          onValueChange={(v) => setApproval(c.city, { action: v as WorkCityApprovalAction })}
                        >
                          <SelectTrigger className="w-[140px] h-8">
                            <SelectValue />
                          </SelectTrigger>
                          <SelectContent>
                            <SelectItem value="use">{i18n.actionAddNew}</SelectItem>
                            <SelectItem value="skip">{i18n.actionSkipNew}</SelectItem>
                          </SelectContent>
                        </Select>
                      </li>
                    ))}
                  </ul>
                </Section>
              )}

              <Section
                icon={<XCircle className="w-4 h-4" style={{ color: colors.error }} />}
                title={i18n.unmatchedTitle}
              >
                {preview.unmatchedEmails.length === 0 ? (
                  <p className={typography.caption} style={{ color: colors.textTertiary }}>
                    {i18n.unmatchedEmpty}
                  </p>
                ) : (
                  <ul className="space-y-1 max-h-40 overflow-y-auto">
                    {preview.unmatchedEmails.map((e) => (
                      <li key={e} className="text-sm" style={{ color: colors.textSecondary }}>
                        {e}
                      </li>
                    ))}
                  </ul>
                )}
              </Section>
            </div>
          )}
        </div>

        <div
          className="flex items-center justify-end gap-3 px-6 py-3 border-t"
          style={{ borderColor: colors.border }}
        >
          <Button variant="outline" onClick={handleClose}>
            {i18n.cancel}
          </Button>
          <Button
            onClick={handleCommit}
            disabled={!preview || committing}
            style={{ backgroundColor: colors.primary }}
          >
            {committing ? i18n.committing : i18n.commit}
          </Button>
        </div>
      </div>
    </div>
  );
}

function Section({
  icon,
  title,
  hint,
  children,
}: {
  icon: React.ReactNode;
  title: string;
  hint?: string;
  children: React.ReactNode;
}) {
  return (
    <div className="rounded-lg p-3" style={{ border: `1px solid ${colors.border}` }}>
      <div className="flex items-center gap-2 mb-2">
        {icon}
        <span className={typography.bodySecondary} style={{ fontWeight: 500 }}>
          {title}
        </span>
      </div>
      {hint && (
        <p className={typography.caption + ' mb-2'} style={{ color: colors.textTertiary }}>
          {hint}
        </p>
      )}
      {children}
    </div>
  );
}
