import { useState } from 'react';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import {
  Alert,
  Badge,
  Button,
  Descriptions,
  Divider,
  Form,
  InputNumber,
  Modal,
  Space,
  Spin,
  Table,
  Tag,
  Timeline,
  Typography,
  Input,
  message,
} from 'antd';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faShareNodes } from '@fortawesome/free-solid-svg-icons';
import { FilePdfOutlined, CustomerServiceOutlined } from '@ant-design/icons';
import { AbrirChamadoModal } from './AbrirChamadoModal';
import type { TableColumnsType } from 'antd';
import { Link, useParams, useNavigate } from '@tanstack/react-router';
import type { PedidoItem, HistoricoPedido } from '@sar/api-interface';
import { SITUA_LABEL } from '@sar/api-interface';
import { useOrderDetail } from '../../lib/queries/orders';
import { useClientOrders } from '../../lib/queries/orders';
import { apiFetch } from '../../lib/api-client';
import { authStore } from '../../lib/auth-store';

const { Title, Text } = Typography;
const { TextArea } = Input;

// ─── Helpers ──────────────────────────────────────────────────────────────────

const SITUA_COLOR: Record<number, string> = {
  0: 'default',
  1: 'warning',
  2: 'processing',
  3: 'error',
  4: 'success',
};

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

function buildShareText(order: {
  numPedSar: string;
  idCliente: number;
  total: string;
  itens: Array<{ descProduto: string | null; qtd: string; precoUnitario: string }>;
}): string {
  const lines = [
    `*Pedido ${order.numPedSar} — Cliente ${order.idCliente}*`,
    '',
    ...order.itens.map(
      (it) =>
        `• ${it.descProduto ?? '?'} × ${Number(it.qtd).toLocaleString('pt-BR')} — ${fmt(it.precoUnitario)} un.`,
    ),
    '',
    `*Total: ${fmt(order.total)}*`,
  ];
  return lines.join('\n');
}

function getRoleFromToken(): string {
  const token = authStore.get();
  if (!token) return 'rep';
  try {
    const payload = JSON.parse(atob(token.split('.')[1] ?? ''));
    return (payload.role as string) ?? 'rep';
  } catch {
    return 'rep';
  }
}

// ─── Subcomponents ────────────────────────────────────────────────────────────

const itemColumns: TableColumnsType<PedidoItem> = [
  { title: 'Código', dataIndex: 'codProduto', width: 100 },
  { title: 'Produto', dataIndex: 'descProduto', ellipsis: true },
  { title: 'Qtd', dataIndex: 'qtd', width: 90, align: 'right' },
  {
    title: 'Preço Unit.',
    dataIndex: 'precoUnitario',
    width: 120,
    align: 'right',
    render: (v: string) => fmt(v),
  },
  {
    title: 'Desc %',
    dataIndex: 'descontoPerc',
    width: 80,
    align: 'right',
    render: (v: string) => `${v}%`,
  },
  {
    title: 'Total',
    dataIndex: 'total',
    width: 130,
    align: 'right',
    render: (v: string) => fmt(v),
  },
];

function HistoryTimeline({ history }: { history: HistoricoPedido[] }) {
  return (
    <Timeline
      items={history.map((h) => ({
        color:
          SITUA_COLOR[h.situaNova] === 'success'
            ? 'green'
            : SITUA_COLOR[h.situaNova] === 'warning'
              ? 'orange'
              : SITUA_COLOR[h.situaNova] === 'error'
                ? 'red'
                : 'blue',
        content: (
          <div>
            <Text strong>{SITUA_LABEL[h.situaNova] ?? String(h.situaNova)}</Text>
            {h.situaAnterior != null && (
              <Text type="secondary">
                {' '}
                (de {SITUA_LABEL[h.situaAnterior] ?? String(h.situaAnterior)})
              </Text>
            )}
            <br />
            <Text type="secondary" style={{ fontSize: 12 }}>
              {new Date(h.changedAt).toLocaleString('pt-BR')} — cod. {h.changedBy}
            </Text>
            {h.nota && (
              <div style={{ marginTop: 4 }}>
                <Text italic>"{h.nota}"</Text>
              </div>
            )}
          </div>
        ),
      }))}
    />
  );
}

// ─── Approve Modal ────────────────────────────────────────────────────────────

function ApproveModal({
  open,
  originalDiscount,
  onConfirm,
  onCancel,
  loading,
}: {
  open: boolean;
  originalDiscount: string;
  onConfirm: (descontoPerc?: number, nota?: string) => void;
  onCancel: () => void;
  loading: boolean;
}) {
  const [disc, setDisc] = useState<number | null>(null);
  const [nota, setNota] = useState('');

  return (
    <Modal
      title="Aprovar Pedido"
      open={open}
      onOk={() => onConfirm(disc ?? undefined, nota || undefined)}
      onCancel={onCancel}
      okText="Confirmar Aprovação"
      cancelText="Voltar"
      confirmLoading={loading}
    >
      <Form layout="vertical">
        <Form.Item
          label={`Desconto global (original: ${originalDiscount}%)`}
          help="Deixe em branco para manter o desconto solicitado."
        >
          <InputNumber
            min={0}
            max={100}
            step={0.5}
            placeholder={originalDiscount}
            value={disc}
            onChange={(v) => setDisc(v)}
            addonAfter="%"
            style={{ width: 160 }}
          />
        </Form.Item>
        <Form.Item label="Observação (opcional)">
          <TextArea
            rows={2}
            value={nota}
            onChange={(e) => setNota(e.target.value)}
            maxLength={300}
          />
        </Form.Item>
      </Form>
    </Modal>
  );
}

// ─── Reject Modal ─────────────────────────────────────────────────────────────

function RejectModal({
  open,
  onConfirm,
  onCancel,
  loading,
}: {
  open: boolean;
  onConfirm: (motivo: string) => void;
  onCancel: () => void;
  loading: boolean;
}) {
  const [motivo, setMotivo] = useState('');

  return (
    <Modal
      title="Recusar Pedido"
      open={open}
      onOk={() => motivo.trim() && onConfirm(motivo.trim())}
      onCancel={onCancel}
      okText="Confirmar Recusa"
      okButtonProps={{ danger: true, disabled: !motivo.trim() }}
      cancelText="Voltar"
      confirmLoading={loading}
    >
      <Form layout="vertical">
        <Form.Item label="Motivo da recusa" required>
          <TextArea
            rows={3}
            value={motivo}
            onChange={(e) => setMotivo(e.target.value)}
            maxLength={500}
            showCount
            placeholder="Informe o motivo para o representante..."
          />
        </Form.Item>
      </Form>
    </Modal>
  );
}

// ─── OrderDetailPage ──────────────────────────────────────────────────────────

export function OrderDetailPage() {
  const { id } = useParams({ from: '/pedidos/$id' });
  const navigate = useNavigate();
  const qc = useQueryClient();
  const { data: order, isLoading, error } = useOrderDetail(id);
  const { data: clientOrders } = useClientOrders(order?.idCliente);

  const role = getRoleFromToken();
  const isErp = order?.fonte === 'erp';
  const canAct = !isErp && role !== 'rep' && order?.situa === 1;
  const canTransmit = !isErp && role === 'rep' && order?.situa === 0;
  const canShare =
    role === 'rep' &&
    (order?.situa === 2 || order?.situa === 4) &&
    typeof navigator !== 'undefined' &&
    !!navigator.share;

  const [approveOpen, setApproveOpen] = useState(false);
  const [rejectOpen, setRejectOpen] = useState(false);
  const [chamadoOpen, setChamadoOpen] = useState(false);
  const [actionError, setActionError] = useState<string | null>(null);

  const approveMutation = useMutation({
    mutationFn: ({ descontoPerc, nota }: { descontoPerc?: number; nota?: string }) =>
      apiFetch(`/orders/${id}/approve`, { method: 'PATCH', body: { descontoPerc, nota } }),
    onSuccess: () => {
      setApproveOpen(false);
      void qc.invalidateQueries({ queryKey: ['orders', id] });
      void qc.invalidateQueries({ queryKey: ['orders'] });
    },
    onError: (e: unknown) => {
      setApproveOpen(false);
      setActionError(e instanceof Error ? e.message : 'Erro ao aprovar');
    },
  });

  const rejectMutation = useMutation({
    mutationFn: (motivo: string) =>
      apiFetch(`/orders/${id}/reject`, { method: 'PATCH', body: { motivo } }),
    onSuccess: () => {
      setRejectOpen(false);
      void qc.invalidateQueries({ queryKey: ['orders', id] });
      void qc.invalidateQueries({ queryKey: ['orders'] });
    },
    onError: (e: unknown) => {
      setRejectOpen(false);
      setActionError(e instanceof Error ? e.message : 'Erro ao recusar');
    },
  });

  const transmitMutation = useMutation({
    mutationFn: () => apiFetch(`/orders/${id}/transmit`, { method: 'PATCH' }),
    onSuccess: () => {
      void qc.invalidateQueries({ queryKey: ['orders', id] });
      void qc.invalidateQueries({ queryKey: ['orders'] });
    },
    // Mensagem de bloqueio de alçada (desconto acima do máximo) vem aqui.
    onError: (e: unknown) => setActionError(e instanceof Error ? e.message : 'Erro ao transmitir'),
  });

  if (isLoading) return <Spin style={{ display: 'block', marginTop: 64 }} />;
  if (error || !order)
    return <Alert type="error" message="Pedido não encontrado." style={{ margin: 24 }} />;

  const timeWaiting =
    order.situa === 1
      ? Math.floor((Date.now() - new Date(order.createdAt).getTime()) / 3_600_000)
      : null;

  // Orçamento: tela mais larga para consulta/revisão com o cliente.
  const isOrcamento = order.situa === 0;

  return (
    <div style={{ padding: 24, maxWidth: isOrcamento ? 1320 : 960, margin: '0 auto' }}>
      <Space align="center" style={{ marginBottom: 16 }} wrap>
        <Link to="/pedidos">← Pedidos</Link>
        <Title level={3} style={{ margin: 0 }}>
          {order.numPedSar}
        </Title>
        <Badge
          status={
            (SITUA_COLOR[order.situa] ?? 'default') as
              | 'default'
              | 'warning'
              | 'processing'
              | 'success'
              | 'error'
          }
          text={
            <Tag color={SITUA_COLOR[order.situa] ?? 'default'}>
              {SITUA_LABEL[order.situa] ?? String(order.situa)}
            </Tag>
          }
        />
        {timeWaiting !== null && timeWaiting > 2 && (
          <Tag color="red">Urgente — {timeWaiting}h aguardando</Tag>
        )}
        <Button
          icon={<FilePdfOutlined />}
          onClick={() => navigate({ to: '/pedidos/$id/imprimir', params: { id } })}
        >
          Gerar PDF
        </Button>
        {canTransmit && (
          <Button
            type="primary"
            loading={transmitMutation.isPending}
            onClick={() => {
              setActionError(null);
              transmitMutation.mutate();
            }}
            style={{ backgroundColor: '#389e0d', borderColor: '#389e0d' }}
          >
            Transmitir pedido
          </Button>
        )}
        {canAct && (
          <Space>
            <Button type="primary" onClick={() => setApproveOpen(true)}>
              Aprovar
            </Button>
            <Button danger onClick={() => setRejectOpen(true)}>
              Recusar
            </Button>
          </Space>
        )}
        {canShare && (
          <Button
            icon={<FontAwesomeIcon icon={faShareNodes} />}
            onClick={async () => {
              try {
                await navigator.share({ text: buildShareText(order) });
              } catch {
                void message.info('Compartilhamento cancelado');
              }
            }}
          >
            Compartilhar
          </Button>
        )}
        {role === 'rep' && !isErp && (order.situa === 2 || order.situa === 4) && (
          <Button icon={<CustomerServiceOutlined />} onClick={() => setChamadoOpen(true)}>
            Abrir Chamado
          </Button>
        )}
      </Space>

      {actionError && (
        <Alert
          type="error"
          message={actionError}
          showIcon
          closable
          onClose={() => setActionError(null)}
          style={{ marginBottom: 16 }}
        />
      )}

      <Descriptions
        bordered
        size={isOrcamento ? 'middle' : 'small'}
        column={isOrcamento ? 3 : 2}
        style={{ marginBottom: 24 }}
      >
        <Descriptions.Item label="Cliente">
          <Link to="/clientes/$id" params={{ id: String(order.idCliente) }}>
            {order.razaoCliente ?? order.nomeCliente ?? `Cód. ${order.idCliente}`}
          </Link>
        </Descriptions.Item>
        <Descriptions.Item label="Representante">
          {order.nomeVendedor ?? `Cód. ${order.codVendedor}`}
        </Descriptions.Item>
        <Descriptions.Item label="Data">
          {new Date(order.dtPedido).toLocaleDateString('pt-BR')}
        </Descriptions.Item>
        {order.aprovadoEm && (
          <Descriptions.Item label="Aprovado em">
            {new Date(order.aprovadoEm).toLocaleString('pt-BR')} — cód. {order.aprovadoPor}
          </Descriptions.Item>
        )}
        {order.formaPagamento && (
          <Descriptions.Item label="Cond. Pagamento" span={2}>
            {order.formaPagamento}
          </Descriptions.Item>
        )}
        <Descriptions.Item label="Total produtos">{fmt(order.totalProdutos)}</Descriptions.Item>
        <Descriptions.Item label="Desc. Global">{order.descontoPerc}%</Descriptions.Item>
        <Descriptions.Item label="Total" span={isOrcamento ? 1 : 2}>
          <Text strong style={{ fontSize: 16 }}>
            {fmt(order.total)}
          </Text>
        </Descriptions.Item>
        {order.endEntrega && (
          <Descriptions.Item label="End. Entrega" span={isOrcamento ? 3 : 2}>
            {order.endEntrega}
          </Descriptions.Item>
        )}
        {order.obs && (
          <Descriptions.Item label="Observações" span={isOrcamento ? 3 : 2}>
            {order.obs}
          </Descriptions.Item>
        )}
        {order.motivoRecusa && (
          <Descriptions.Item label="Motivo Recusa" span={isOrcamento ? 3 : 2}>
            <Text type="danger">{order.motivoRecusa}</Text>
          </Descriptions.Item>
        )}
      </Descriptions>

      <Divider titlePlacement="left">Itens ({order.itens.length})</Divider>
      <Table<PedidoItem>
        rowKey="id"
        columns={itemColumns}
        dataSource={order.itens}
        pagination={false}
        size={isOrcamento ? 'middle' : 'small'}
        style={{ marginBottom: 24 }}
      />

      {clientOrders && clientOrders.length > 0 && (
        <>
          <Divider titlePlacement="left">Outros Pedidos do Cliente</Divider>
          <Table
            rowKey="id"
            size="small"
            pagination={false}
            dataSource={clientOrders.filter((o) => o.id !== id).slice(0, 5)}
            columns={[
              {
                title: 'Nº',
                dataIndex: 'numPedSar',
                width: 110,
                render: (n: string, r: { id: string }) => (
                  <Link to="/pedidos/$id" params={{ id: r.id }}>
                    {n}
                  </Link>
                ),
              },
              {
                title: 'Status',
                dataIndex: 'situa',
                width: 130,
                render: (s: number) => (
                  <Tag color={SITUA_COLOR[s] ?? 'default'}>{SITUA_LABEL[s] ?? String(s)}</Tag>
                ),
              },
              {
                title: 'Total',
                dataIndex: 'total',
                align: 'right' as const,
                render: (v: string) => fmt(v),
              },
              {
                title: 'Data',
                dataIndex: 'dtPedido',
                render: (v: string) => new Date(v).toLocaleDateString('pt-BR'),
              },
            ]}
            style={{ marginBottom: 24 }}
          />
        </>
      )}

      <Divider titlePlacement="left">Histórico do Pedido</Divider>
      <HistoryTimeline history={order.historico} />

      <ApproveModal
        open={approveOpen}
        originalDiscount={order.descontoPerc}
        onConfirm={(descontoPerc, nota) => approveMutation.mutate({ descontoPerc, nota })}
        onCancel={() => setApproveOpen(false)}
        loading={approveMutation.isPending}
      />
      <RejectModal
        open={rejectOpen}
        onConfirm={(motivo) => rejectMutation.mutate(motivo)}
        onCancel={() => setRejectOpen(false)}
        loading={rejectMutation.isPending}
      />
      {order && (
        <AbrirChamadoModal
          open={chamadoOpen}
          onClose={() => setChamadoOpen(false)}
          idPedido={order.id}
          numPedSar={parseInt(order.numPedSar.replace(/\D/g, ''), 10) || undefined}
          nomeCliente={order.razaoCliente ?? order.nomeCliente}
          idCliente={order.idCliente}
          itens={order.itens}
        />
      )}
    </div>
  );
}
