import { useState } from 'react';
import {
  Alert,
  Badge,
  Button,
  Card,
  Col,
  Collapse,
  Flex,
  Form,
  Input,
  InputNumber,
  Modal,
  Row,
  Select,
  Skeleton,
  Space,
  Tag,
  Tooltip,
  Typography,
} from 'antd';
import {
  ArrowRightOutlined,
  DeleteOutlined,
  EditOutlined,
  PlusOutlined,
  TrophyOutlined,
} from '@ant-design/icons';
import type {
  Oportunidade,
  EtapaFunil,
  CreateOportunidadeDto,
  UpdateOportunidadeDto,
} from '@sar/api-interface';
import { ETAPAS_FUNIL } from '@sar/api-interface';
import {
  useFunil,
  useCreateOportunidade,
  useUpdateOportunidade,
  useDeleteOportunidade,
} from '../../lib/queries/funil';

const { Title, Text } = Typography;

const ETAPA_CONFIG: Record<EtapaFunil, { label: string; cor: string; corBg: string }> = {
  lead: { label: 'Lead', cor: '#64748b', corBg: '#F8FAFC' },
  proposta: { label: 'Proposta', cor: '#2563EB', corBg: '#EFF6FF' },
  negociacao: { label: 'Negociação', cor: '#D97706', corBg: '#FFFBEB' },
  ganho: { label: 'Ganho', cor: '#16A34A', corBg: '#F0FDF4' },
  perdido: { label: 'Perdido', cor: '#DC2626', corBg: '#FEF2F2' },
};

const PROXIMA: Partial<Record<EtapaFunil, EtapaFunil>> = {
  lead: 'proposta',
  proposta: 'negociacao',
  negociacao: 'ganho',
};

const ANTERIOR: Partial<Record<EtapaFunil, EtapaFunil>> = {
  proposta: 'lead',
  negociacao: 'proposta',
  ganho: 'negociacao',
};

function fmt(v: string | null | undefined): string {
  if (!v) return '';
  return Number(v).toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' });
}

function diasDesde(iso: string): number {
  return Math.floor((Date.now() - new Date(iso).getTime()) / 86_400_000);
}

function nomePrincipal(op: Oportunidade): string {
  return op.nomeCliente ?? op.nomeProspect ?? op.empresaProspect ?? `Oport. #${op.id}`;
}

// ─── Card ────────────────────────────────────────────────────────────────────

function OportCard({
  op,
  onEdit,
  onMover,
  onDeletar,
}: {
  op: Oportunidade;
  onEdit: () => void;
  onMover: (etapa: EtapaFunil) => void;
  onDeletar: () => void;
}) {
  const dias = diasDesde(op.updatedAt);
  const prox = PROXIMA[op.etapa as EtapaFunil];
  const ant = ANTERIOR[op.etapa as EtapaFunil];

  return (
    <Card
      size="small"
      style={{ marginBottom: 10, borderRadius: 8, border: '1px solid #E2E8F0' }}
      styles={{ body: { padding: '10px 12px' } }}
    >
      <Flex justify="space-between" align="flex-start" gap={8}>
        <div style={{ flex: 1, minWidth: 0 }}>
          <Text strong style={{ fontSize: 13, color: '#1e293b', display: 'block' }} ellipsis>
            {nomePrincipal(op)}
          </Text>
          {op.titulo && (
            <Text type="secondary" style={{ fontSize: 11 }} ellipsis>
              {op.titulo}
            </Text>
          )}
        </div>
        <Space size={2}>
          <Tooltip title="Editar">
            <Button size="small" type="text" icon={<EditOutlined />} onClick={onEdit} />
          </Tooltip>
          <Tooltip title="Excluir">
            <Button
              size="small"
              type="text"
              danger
              icon={<DeleteOutlined />}
              onClick={() =>
                Modal.confirm({
                  title: 'Excluir oportunidade?',
                  content: 'Esta ação não pode ser desfeita.',
                  okText: 'Excluir',
                  okButtonProps: { danger: true },
                  onOk: onDeletar,
                })
              }
            />
          </Tooltip>
        </Space>
      </Flex>

      <Flex justify="space-between" align="center" style={{ marginTop: 6 }}>
        <Text style={{ fontSize: 12, color: '#003B8E', fontWeight: 600 }}>
          {op.valorEstimado ? fmt(op.valorEstimado) : '—'}
        </Text>
        <Text type="secondary" style={{ fontSize: 11 }}>
          {dias === 0 ? 'hoje' : `${dias}d`}
        </Text>
      </Flex>

      <Flex gap={4} style={{ marginTop: 8 }}>
        {ant && (
          <Button
            size="small"
            style={{ fontSize: 11, padding: '0 6px', color: '#64748b', borderColor: '#CBD5E1' }}
            onClick={() => onMover(ant)}
          >
            ← {ETAPA_CONFIG[ant].label}
          </Button>
        )}
        <div style={{ flex: 1 }} />
        {op.etapa !== 'perdido' && op.etapa !== 'ganho' && (
          <Tooltip title="Marcar como perdido">
            <Button
              size="small"
              danger
              ghost
              style={{ fontSize: 11, padding: '0 6px' }}
              onClick={() => onMover('perdido')}
            >
              Perdido
            </Button>
          </Tooltip>
        )}
        {prox && (
          <Button
            size="small"
            type="primary"
            style={{
              fontSize: 11,
              padding: '0 6px',
              background: ETAPA_CONFIG[prox].cor,
              borderColor: ETAPA_CONFIG[prox].cor,
            }}
            onClick={() => onMover(prox)}
          >
            {ETAPA_CONFIG[prox].label} <ArrowRightOutlined />
          </Button>
        )}
        {op.etapa === 'ganho' && (
          <Tag color="green" style={{ fontSize: 11, margin: 0 }}>
            <TrophyOutlined /> Ganho
          </Tag>
        )}
      </Flex>
    </Card>
  );
}

// ─── Modal criar/editar ───────────────────────────────────────────────────────

type FormValues = {
  titulo: string;
  etapa: EtapaFunil;
  nomeProspect?: string;
  empresaProspect?: string;
  valorEstimado?: number;
  observacoes?: string;
};

function OportModal({
  open,
  initial,
  etapaInicial,
  onClose,
  onSave,
}: {
  open: boolean;
  initial?: Oportunidade | null;
  etapaInicial: EtapaFunil;
  onClose: () => void;
  onSave: (dto: CreateOportunidadeDto | UpdateOportunidadeDto) => Promise<void>;
}) {
  const [form] = Form.useForm<FormValues>();
  const [saving, setSaving] = useState(false);

  const handleOk = async () => {
    const values = await form.validateFields();
    setSaving(true);
    try {
      await onSave({
        titulo: values.titulo,
        etapa: values.etapa,
        nomeProspect: values.nomeProspect ?? null,
        empresaProspect: values.empresaProspect ?? null,
        valorEstimado: values.valorEstimado ?? null,
        observacoes: values.observacoes ?? null,
      });
      onClose();
    } catch {
      // erro já notificado pelo handler global do QueryClient; modal fica aberto
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal
      open={open}
      title={initial ? 'Editar Oportunidade' : 'Nova Oportunidade'}
      width={520}
      centered
      onCancel={onClose}
      onOk={handleOk}
      okText={initial ? 'Salvar' : 'Criar'}
      confirmLoading={saving}
      afterOpenChange={(vis) => {
        if (vis) {
          form.setFieldsValue(
            initial
              ? {
                  titulo: initial.titulo,
                  etapa: initial.etapa as EtapaFunil,
                  nomeProspect: initial.nomeProspect ?? undefined,
                  empresaProspect: initial.empresaProspect ?? undefined,
                  valorEstimado: initial.valorEstimado ? Number(initial.valorEstimado) : undefined,
                  observacoes: initial.observacoes ?? undefined,
                }
              : { etapa: etapaInicial },
          );
        } else {
          form.resetFields();
        }
      }}
    >
      <Form form={form} layout="vertical" style={{ marginTop: 8 }}>
        <Form.Item
          name="titulo"
          label="Título / produto de interesse"
          rules={[{ required: true, message: 'Informe o título' }]}
        >
          <Input placeholder="Ex: Reposição de estoque Q3" />
        </Form.Item>
        <Row gutter={12}>
          <Col span={12}>
            <Form.Item name="nomeProspect" label="Nome do contato">
              <Input placeholder="João Silva" />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item name="empresaProspect" label="Empresa">
              <Input placeholder="Empresa XYZ" />
            </Form.Item>
          </Col>
        </Row>
        <Row gutter={12}>
          <Col span={12}>
            <Form.Item name="valorEstimado" label="Valor estimado (R$)">
              <InputNumber
                style={{ width: '100%' }}
                min={0}
                precision={2}
                formatter={(v) => String(v).replace(/\B(?=(\d{3})+(?!\d))/g, '.')}
                parser={(v) => Number((v ?? '').replace(/\./g, '').replace(',', '.'))}
                placeholder="0,00"
              />
            </Form.Item>
          </Col>
          <Col span={12}>
            <Form.Item name="etapa" label="Estágio">
              <Select
                options={ETAPAS_FUNIL.map((e) => ({
                  value: e,
                  label: ETAPA_CONFIG[e].label,
                }))}
              />
            </Form.Item>
          </Col>
        </Row>
        <Form.Item name="observacoes" label="Observações">
          <Input.TextArea rows={3} placeholder="Anotações sobre o lead..." />
        </Form.Item>
      </Form>
    </Modal>
  );
}

// ─── Coluna kanban ────────────────────────────────────────────────────────────

function KanbanColuna({
  etapa,
  ops,
  onEdit,
  onMover,
  onDeletar,
  onNovo,
}: {
  etapa: EtapaFunil;
  ops: Oportunidade[];
  onEdit: (op: Oportunidade) => void;
  onMover: (id: number, etapa: EtapaFunil) => void;
  onDeletar: (id: number) => void;
  onNovo: (etapa: EtapaFunil) => void;
}) {
  const cfg = ETAPA_CONFIG[etapa];
  const total = ops.reduce((s, o) => s + (o.valorEstimado ? Number(o.valorEstimado) : 0), 0);

  return (
    <div
      style={{
        minWidth: 240,
        flex: 1,
        background: cfg.corBg,
        borderRadius: 10,
        border: `1px solid ${cfg.cor}33`,
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      <div
        style={{
          padding: '10px 14px 8px',
          borderBottom: `2px solid ${cfg.cor}`,
          borderRadius: '10px 10px 0 0',
        }}
      >
        <Flex justify="space-between" align="center">
          <Space size={6}>
            <Text strong style={{ color: cfg.cor, fontSize: 13 }}>
              {cfg.label}
            </Text>
            <Badge count={ops.length} color={cfg.cor} style={{ fontSize: 11 }} />
          </Space>
          {total > 0 && (
            <Text style={{ fontSize: 11, color: cfg.cor, fontWeight: 600 }}>
              {total.toLocaleString('pt-BR', { style: 'currency', currency: 'BRL' })}
            </Text>
          )}
        </Flex>
      </div>

      <div
        style={{
          padding: '10px 10px 4px',
          flex: 1,
          overflowY: 'auto',
          maxHeight: 'calc(100vh - 260px)',
        }}
      >
        {ops.map((op) => (
          <OportCard
            key={op.id}
            op={op}
            onEdit={() => onEdit(op)}
            onMover={(e) => onMover(op.id, e)}
            onDeletar={() => onDeletar(op.id)}
          />
        ))}
      </div>

      <div style={{ padding: '4px 10px 10px' }}>
        <Button
          block
          type="dashed"
          icon={<PlusOutlined />}
          style={{ borderColor: cfg.cor, color: cfg.cor, fontSize: 12 }}
          onClick={() => onNovo(etapa)}
        >
          Adicionar
        </Button>
      </div>
    </div>
  );
}

// ─── FunilPage ────────────────────────────────────────────────────────────────

export function FunilPage() {
  const { data, isLoading, isError, error } = useFunil();
  const criar = useCreateOportunidade();
  const atualizar = useUpdateOportunidade();
  const deletar = useDeleteOportunidade();

  const [modalOpen, setModalOpen] = useState(false);
  const [editOp, setEditOp] = useState<Oportunidade | null>(null);
  const [etapaModal, setEtapaModal] = useState<EtapaFunil>('lead');

  const abrirNovo = (etapa: EtapaFunil) => {
    setEditOp(null);
    setEtapaModal(etapa);
    setModalOpen(true);
  };

  const abrirEditar = (op: Oportunidade) => {
    setEditOp(op);
    setEtapaModal(op.etapa as EtapaFunil);
    setModalOpen(true);
  };

  const handleSave = async (dto: CreateOportunidadeDto | UpdateOportunidadeDto) => {
    if (editOp) {
      await atualizar.mutateAsync({ id: editOp.id, dto });
    } else {
      await criar.mutateAsync(dto as CreateOportunidadeDto);
    }
  };

  const handleMover = (id: number, etapa: EtapaFunil) => {
    atualizar.mutate({ id, dto: { etapa } });
  };

  const handleDeletar = (id: number) => {
    deletar.mutate(id);
  };

  const etapasPrincipais: EtapaFunil[] = ['lead', 'proposta', 'negociacao', 'ganho'];
  const perdidos = data?.perdido ?? [];

  return (
    <div
      style={{
        height: 'calc(100vh - var(--layout-topbar-height) - 48px)',
        display: 'flex',
        flexDirection: 'column',
      }}
    >
      <Flex align="center" justify="space-between" style={{ marginBottom: 16, flexShrink: 0 }}>
        <div>
          <Title level={4} style={{ margin: 0, color: '#003B8E' }}>
            Funil de Vendas
          </Title>
          <Text type="secondary" style={{ fontSize: 13 }}>
            Acompanhe seus leads até o fechamento do pedido
          </Text>
        </div>
        <Button
          type="primary"
          icon={<PlusOutlined />}
          onClick={() => abrirNovo('lead')}
          style={{ background: '#003B8E' }}
        >
          Novo Lead
        </Button>
      </Flex>

      {isError && (
        <Alert
          type="error"
          showIcon
          message="Erro ao carregar funil"
          description={error instanceof Error ? error.message : 'Erro desconhecido'}
          style={{ marginBottom: 16, flexShrink: 0 }}
        />
      )}

      {isLoading ? (
        <Skeleton active paragraph={{ rows: 8 }} />
      ) : (
        <>
          <div style={{ display: 'flex', gap: 12, flex: 1, overflowX: 'auto', paddingBottom: 8 }}>
            {etapasPrincipais.map((etapa) => (
              <KanbanColuna
                key={etapa}
                etapa={etapa}
                ops={data?.[etapa] ?? []}
                onEdit={abrirEditar}
                onMover={handleMover}
                onDeletar={handleDeletar}
                onNovo={abrirNovo}
              />
            ))}
          </div>

          {perdidos.length > 0 && (
            <div style={{ marginTop: 12, flexShrink: 0 }}>
              <Collapse
                ghost
                size="small"
                items={[
                  {
                    key: 'perdidos',
                    label: (
                      <Text style={{ color: '#DC2626', fontSize: 13 }}>
                        Perdidos ({perdidos.length})
                      </Text>
                    ),
                    children: (
                      <Row gutter={[10, 10]}>
                        {perdidos.map((op) => (
                          <Col key={op.id} xs={24} sm={12} md={8} lg={6}>
                            <OportCard
                              op={op}
                              onEdit={() => abrirEditar(op)}
                              onMover={(e) => handleMover(op.id, e)}
                              onDeletar={() => handleDeletar(op.id)}
                            />
                          </Col>
                        ))}
                      </Row>
                    ),
                  },
                ]}
              />
            </div>
          )}
        </>
      )}

      <OportModal
        open={modalOpen}
        initial={editOp}
        etapaInicial={etapaModal}
        onClose={() => setModalOpen(false)}
        onSave={handleSave}
      />
    </div>
  );
}
