import { useState, useEffect } from 'react';
import { useSearchParams } from 'react-router-dom';
import {
  Card,
  Button,
  Space,
  Typography,
  Tag,
  Divider,
  Row,
  Col,
  Modal,
  Select,
  Spin,
  Empty,
  Alert,
  Popconfirm,
  Avatar,
  DatePicker,
} from 'antd';
import { showSuccess, showError } from '@/lib/errorHandling';
import type { Dayjs } from 'dayjs';
import dayjs from 'dayjs';
import {
  PlusOutlined,
  BankOutlined,
  CheckCircleOutlined,
  CloseCircleOutlined,
  ClockCircleOutlined,
  ExclamationCircleOutlined,
  DisconnectOutlined,
  LinkOutlined,
  ReloadOutlined,
  InboxOutlined,
} from '@ant-design/icons';
import { useBankConnections, useAvailableBanks } from '@/api/queries/bankConnectionQueries';
import { useStartBankConnection, useDisconnectBankConnection, useLinkBankAccount, useReconnectBankConnection, useArchiveBankConnection } from '@/api/mutations/bankConnectionMutations';
import { useCreateAccount } from '@/api/mutations/accountMutations';
import { useActiveAccounts } from '@/api/queries/accountQueries';
import type { BankConnection, BankAccountInfo } from '@/api/queries/bankConnectionQueries';

const { Title, Text } = Typography;

interface BankConnectionsTabProps {
  companyId: string | undefined;
}

function getStatusTag(status: BankConnection['status'], isActive: boolean) {
  if (status === 'established' && isActive) {
    return <Tag icon={<CheckCircleOutlined />} color="success">Aktiv</Tag>;
  }
  if (status === 'established' && !isActive) {
    return <Tag icon={<ClockCircleOutlined />} color="warning">Udløbet</Tag>;
  }
  if (status === 'initiated') {
    return <Tag icon={<ClockCircleOutlined />} color="processing">Afventer</Tag>;
  }
  if (status === 'failed') {
    return <Tag icon={<CloseCircleOutlined />} color="error">Fejlet</Tag>;
  }
  if (status === 'disconnected') {
    return <Tag icon={<DisconnectOutlined />} color="default">Afbrudt</Tag>;
  }
  return <Tag>{status}</Tag>;
}

function formatDate(dateString: string) {
  return new Date(dateString).toLocaleDateString('da-DK', {
    year: 'numeric',
    month: 'short',
    day: 'numeric',
  });
}

export default function BankConnectionsTab({ companyId }: BankConnectionsTabProps) {
  const [searchParams, setSearchParams] = useSearchParams();
  const [isAddModalOpen, setIsAddModalOpen] = useState(false);
  const [selectedBank, setSelectedBank] = useState<string | null>(null);
  const [psuType, setPsuType] = useState<string>('personal');

  // Link account modal state
  const [isLinkModalOpen, setIsLinkModalOpen] = useState(false);
  const [linkingAccount, setLinkingAccount] = useState<{ connectionId: string; account: BankAccountInfo } | null>(null);
  const [selectedLinkedAccount, setSelectedLinkedAccount] = useState<string | null>(null);
  const [importFromDate, setImportFromDate] = useState<Dayjs | null>(dayjs());

  const { data: connections, isLoading: isLoadingConnections, error: connectionsError, refetch } = useBankConnections(companyId);
  const { data: activeAccounts } = useActiveAccounts(companyId);

  // Handle callback from bank authorization
  useEffect(() => {
    const success = searchParams.get('success');
    const error = searchParams.get('error');

    if (success === 'true') {
      showSuccess('Bankforbindelse oprettet!');
      refetch(); // Refresh connections list
      // Clean up URL
      setSearchParams({ tab: 'bankAccounts' });
    } else if (error) {
      const errorMessages: Record<string, string> = {
        'missing_parameters': 'Manglende parametre fra banken',
        'completion_failed': 'Kunne ikke fuldføre forbindelsen',
        'internal_error': 'Der opstod en intern fejl',
      };
      showError(errorMessages[error] || `Fejl: ${error}`);
      setSearchParams({ tab: 'bankAccounts' });
    }
  }, [searchParams, setSearchParams, refetch]);
  const { data: availableBanks, isLoading: isLoadingBanks } = useAvailableBanks('DK', {
    enabled: isAddModalOpen,
  });

  const startConnection = useStartBankConnection();
  const disconnectConnection = useDisconnectBankConnection();
  const reconnectConnection = useReconnectBankConnection();
  const archiveConnection = useArchiveBankConnection();
  const linkBankAccount = useLinkBankAccount();
  const createAccount = useCreateAccount();

  // Filter accounts for linking: only bank accounts (1970-1989)
  const linkableAccounts = activeAccounts?.filter((acc) => {
    const accountNum = parseInt(acc.accountNumber, 10);
    return accountNum >= 1970 && accountNum <= 1989;
  }) || [];

  // Find next available bank account number (1970-1989)
  const getNextBankAccountNumber = () => {
    const usedNumbers = new Set(
      linkableAccounts.map((acc) => parseInt(acc.accountNumber, 10))
    );
    for (let num = 1970; num <= 1989; num++) {
      if (!usedNumbers.has(num)) {
        return num.toString();
      }
    }
    return '1970'; // Fallback
  };

  const handleCreateBankAccount = async () => {
    if (!companyId) return;

    const accountNumber = getNextBankAccountNumber();
    const accountName = linkableAccounts.length === 0
      ? 'Bankkonto'
      : `Bankkonto ${linkableAccounts.length + 1}`;

    try {
      const newAccount = await createAccount.mutateAsync({
        companyId,
        accountNumber,
        name: accountName,
        accountType: 'asset',
        description: 'Bankkonto til Open Banking',
      });
      showSuccess(`Bankkonto "${accountName}" oprettet`);
      // Auto-select the newly created account
      setSelectedLinkedAccount(newAccount.id);
    } catch (error) {
      showError(error, 'Kunne ikke oprette bankkonto');
      console.error('Failed to create bank account:', error);
    }
  };

  const handleOpenLinkModal = (connectionId: string, account: BankAccountInfo) => {
    setLinkingAccount({ connectionId, account });
    setSelectedLinkedAccount(account.linkedAccountId || null);
    setImportFromDate(account.importFromDate ? dayjs(account.importFromDate) : dayjs());
    setIsLinkModalOpen(true);
  };

  const handleLinkAccount = async () => {
    if (!linkingAccount || !selectedLinkedAccount || !companyId) {
      showError('Vælg venligst en konto');
      return;
    }

    try {
      await linkBankAccount.mutateAsync({
        input: {
          connectionId: linkingAccount.connectionId,
          bankAccountId: linkingAccount.account.accountId,
          linkedAccountId: selectedLinkedAccount,
          importFromDate: importFromDate?.toISOString(),
        },
        companyId,
      });
      showSuccess('Bankkonto koblet til finanskonto');
      setIsLinkModalOpen(false);
      setLinkingAccount(null);
      setSelectedLinkedAccount(null);
      setImportFromDate(dayjs());
    } catch (error) {
      showError(error, 'Kunne ikke koble bankkonto');
      console.error('Failed to link account:', error);
    }
  };

  const handleAddBankAccount = async () => {
    if (!selectedBank || !companyId) {
      showError('Vælg venligst en bank');
      return;
    }

    try {
      // Use backend callback URL - backend will handle OAuth and redirect back to frontend
      const apiBaseUrl = import.meta.env.VITE_API_URL || 'https://localhost:5001';
      const redirectUrl = `${apiBaseUrl}/api/banking/callback`;
      console.log('Enable Banking redirect URL:', redirectUrl);

      const result = await startConnection.mutateAsync({
        companyId,
        aspspName: selectedBank,
        redirectUrl,
        psuType,
      });

      // Redirect to bank authorization
      // The state parameter contains connection ID, backend will use it to complete
      window.location.href = result.authorizationUrl;
    } catch (error) {
      showError(error, 'Kunne ikke starte bankforbindelse');
      console.error('Failed to start bank connection:', error);
    }
  };

  const handleDisconnect = async (connectionId: string) => {
    if (!companyId) return;

    try {
      await disconnectConnection.mutateAsync({ id: connectionId, companyId });
      showSuccess('Bankforbindelse afbrudt');
    } catch (error) {
      showError(error, 'Kunne ikke afbryde bankforbindelse');
      console.error('Failed to disconnect:', error);
    }
  };

  const handleReconnect = async (connectionId: string, psuType?: string) => {
    if (!companyId) return;

    try {
      // Use backend callback URL - backend will handle OAuth and redirect back to frontend
      const apiBaseUrl = import.meta.env.VITE_API_URL || 'https://localhost:5001';
      const redirectUrl = `${apiBaseUrl}/api/banking/callback`;

      const result = await reconnectConnection.mutateAsync({
        input: {
          connectionId,
          redirectUrl,
          psuType: psuType ?? 'personal',
        },
        companyId,
      });

      // Redirect to bank authorization
      window.location.href = result.authorizationUrl;
    } catch (error) {
      showError(error, 'Kunne ikke genoptage bankforbindelse');
      console.error('Failed to reconnect bank connection:', error);
    }
  };

  const handleArchive = async (connectionId: string) => {
    if (!companyId) return;

    try {
      await archiveConnection.mutateAsync({ id: connectionId, companyId });
      showSuccess('Bankforbindelse arkiveret');
    } catch (error) {
      showError(error, 'Kunne ikke arkivere bankforbindelse');
      console.error('Failed to archive:', error);
    }
  };

  const activeConnections = connections?.filter(c => c.status === 'established' && c.isActive) || [];
  const otherConnections = connections?.filter(c => !(c.status === 'established' && c.isActive)) || [];

  if (isLoadingConnections) {
    return (
      <Card>
        <div style={{ textAlign: 'center', padding: 40 }}>
          <Spin size="large" />
          <div style={{ marginTop: 16 }}>
            <Text type="secondary">Indlæser bankforbindelser...</Text>
          </div>
        </div>
      </Card>
    );
  }

  if (connectionsError) {
    return (
      <Card>
        <Alert
          message="Fejl ved indlæsning"
          description="Kunne ikke indlæse bankforbindelser. Prøv at genindlæse siden."
          type="error"
          showIcon
        />
      </Card>
    );
  }

  return (
    <Card>
      <Space direction="vertical" style={{ width: '100%' }} size="large">
        {/* Header */}
        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <div>
            <Title level={5} style={{ margin: 0 }}>Tilknyttede bankkonti</Title>
            <Text type="secondary">
              Forbind dine bankkonti via Open Banking for automatisk import af transaktioner
            </Text>
          </div>
          <Button
            type="primary"
            icon={<PlusOutlined />}
            onClick={() => setIsAddModalOpen(true)}
          >
            Tilføj bankkonto
          </Button>
        </div>

        <Divider style={{ margin: '12px 0' }} />

        {/* Active Connections */}
        {activeConnections.length > 0 && (
          <>
            <Title level={5} style={{ margin: 0 }}>Aktive forbindelser</Title>
            {activeConnections.map((connection) => (
              <BankConnectionCard
                key={connection.id}
                connection={connection}
                onDisconnect={handleDisconnect}
                onReconnect={handleReconnect}
                onArchive={handleArchive}
                onLinkAccount={handleOpenLinkModal}
                isDisconnecting={disconnectConnection.isPending}
                isReconnecting={reconnectConnection.isPending}
                isArchiving={archiveConnection.isPending}
              />
            ))}
          </>
        )}

        {/* Empty State */}
        {connections?.length === 0 && (
          <Empty
            image={<BankOutlined style={{ fontSize: 48, color: '#d9d9d9' }} />}
            description={
              <Space direction="vertical" size={0}>
                <Text>Ingen bankkonti tilknyttet</Text>
                <Text type="secondary">
                  Tilføj en bankkonto for at importere transaktioner automatisk
                </Text>
              </Space>
            }
          >
            <Button type="primary" onClick={() => setIsAddModalOpen(true)}>
              Tilføj din første bankkonto
            </Button>
          </Empty>
        )}

        {/* Other Connections (inactive, failed, etc.) */}
        {otherConnections.length > 0 && (
          <>
            <Divider />
            <Title level={5} style={{ margin: 0 }}>
              <Text type="secondary">Tidligere forbindelser</Text>
            </Title>
            {otherConnections.map((connection) => (
              <BankConnectionCard
                key={connection.id}
                connection={connection}
                onDisconnect={handleDisconnect}
                onReconnect={handleReconnect}
                onArchive={handleArchive}
                onLinkAccount={handleOpenLinkModal}
                isDisconnecting={disconnectConnection.isPending}
                isReconnecting={reconnectConnection.isPending}
                isArchiving={archiveConnection.isPending}
              />
            ))}
          </>
        )}
      </Space>

      {/* Add Bank Modal */}
      <Modal
        title="Tilføj bankkonto"
        open={isAddModalOpen}
        onCancel={() => {
          setIsAddModalOpen(false);
          setSelectedBank(null);
        }}
        onOk={handleAddBankAccount}
        okText="Forbind bank"
        cancelText="Annuller"
        confirmLoading={startConnection.isPending}
        okButtonProps={{ disabled: !selectedBank }}
      >
        <Space direction="vertical" style={{ width: '100%' }} size="middle">
          <Alert
            message="Sikker bankforbindelse"
            description="Du vil blive sendt til din banks hjemmeside for at godkende forbindelsen. Vi gemmer aldrig dine bankoplysninger."
            type="info"
            showIcon
          />

          <div>
            <Text strong>Vælg bank</Text>
            <Select
              style={{ width: '100%', marginTop: 8 }}
              placeholder="Søg efter din bank..."
              showSearch
              loading={isLoadingBanks}
              value={selectedBank}
              onChange={setSelectedBank}
              filterOption={(input, option) =>
                (option?.searchText as string)?.toLowerCase().includes(input.toLowerCase()) ?? false
              }
              options={availableBanks?.map((bank) => ({
                value: bank.name,
                searchText: bank.name,
                label: (
                  <Space>
                    {bank.logo ? (
                      <Avatar src={bank.logo} size="small" />
                    ) : (
                      <BankOutlined />
                    )}
                    {bank.name}
                  </Space>
                ),
              }))}
            />
          </div>

          <div>
            <Text strong>Kontotype</Text>
            <Select
              style={{ width: '100%', marginTop: 8 }}
              value={psuType}
              onChange={setPsuType}
              options={[
                { value: 'personal', label: 'Privatkonto' },
                { value: 'business', label: 'Erhvervskonto' },
              ]}
            />
          </div>
        </Space>
      </Modal>

      {/* Link Bank Account Modal */}
      <Modal
        title="Kobl bankkonto til finanskonto"
        open={isLinkModalOpen}
        onCancel={() => {
          setIsLinkModalOpen(false);
          setLinkingAccount(null);
          setSelectedLinkedAccount(null);
          setImportFromDate(dayjs());
        }}
        onOk={handleLinkAccount}
        okText="Kobl konto"
        cancelText="Annuller"
        confirmLoading={linkBankAccount.isPending}
        okButtonProps={{ disabled: !selectedLinkedAccount }}
      >
        <Space direction="vertical" style={{ width: '100%' }} size="middle">
          {linkingAccount && (
            <Alert
              message={`Bankkonto: ${linkingAccount.account.name || linkingAccount.account.iban}`}
              description={`IBAN: ${linkingAccount.account.iban}`}
              type="info"
              showIcon
              icon={<BankOutlined />}
            />
          )}

          <div>
            <Text strong>Vælg bankkonto (1970-1989)</Text>
            <Text type="secondary" style={{ display: 'block', marginBottom: 8 }}>
              Banktransaktioner vil blive importeret til denne konto
            </Text>
            {linkableAccounts.length > 0 ? (
              <Select
                style={{ width: '100%' }}
                placeholder="Søg efter konto..."
                showSearch
                value={selectedLinkedAccount}
                onChange={setSelectedLinkedAccount}
                filterOption={(input, option) =>
                  (option?.searchText as string)?.toLowerCase().includes(input.toLowerCase()) ?? false
                }
                options={linkableAccounts.map((acc) => ({
                  value: acc.id,
                  searchText: `${acc.accountNumber} ${acc.name}`,
                  label: (
                    <Space>
                      <Text strong>{acc.accountNumber}</Text>
                      <Text>{acc.name}</Text>
                    </Space>
                  ),
                }))}
              />
            ) : (
              <Alert
                message="Ingen bankkonti fundet"
                description="Der er ingen bankkonti (1970-1989) i kontoplanen. Opret en bankkonto for at fortsætte."
                type="warning"
                showIcon
              />
            )}
            <Button
              type="dashed"
              icon={<PlusOutlined />}
              onClick={handleCreateBankAccount}
              loading={createAccount.isPending}
              style={{ width: '100%', marginTop: 8 }}
            >
              Opret ny bankkonto
            </Button>
          </div>

          <div>
            <Text strong>Importer transaktioner fra</Text>
            <Text type="secondary" style={{ display: 'block', marginBottom: 8 }}>
              Transaktioner før denne dato vil ikke blive importeret
            </Text>
            <DatePicker
              style={{ width: '100%' }}
              value={importFromDate}
              onChange={setImportFromDate}
              format="DD-MM-YYYY"
              placeholder="Vælg startdato"
            />
          </div>
        </Space>
      </Modal>
    </Card>
  );
}

interface BankConnectionCardProps {
  connection: BankConnection;
  onDisconnect: (id: string) => void;
  onReconnect: (id: string) => void;
  onArchive: (id: string) => void;
  onLinkAccount: (connectionId: string, account: BankAccountInfo) => void;
  isDisconnecting: boolean;
  isReconnecting: boolean;
  isArchiving: boolean;
}

function BankConnectionCard({ connection, onDisconnect, onReconnect, onArchive, onLinkAccount, isDisconnecting, isReconnecting, isArchiving }: BankConnectionCardProps) {
  // Allow disconnecting/removing any connection that isn't already disconnected
  const canDisconnect = connection.status !== 'disconnected';
  // Allow reconnecting for initiated (pending), failed, disconnected, or expired connections
  const isExpired = connection.status === 'established' && !connection.isActive;
  const canReconnect = connection.status === 'initiated' || connection.status === 'failed' || connection.status === 'disconnected' || isExpired;
  // Allow archiving for non-active connections (expired, failed, disconnected, or stuck in initiated)
  const canArchive = !connection.isActive || connection.status !== 'established';
  const canLink = connection.status === 'established' && connection.isActive;

  return (
    <Card size="small" style={{ marginTop: 8 }}>
      <Row align="middle" justify="space-between">
        <Col flex="auto">
          <Space direction="vertical" size={0} style={{ width: '100%' }}>
            <Space>
              <BankOutlined style={{ fontSize: 16 }} />
              <Text strong>{connection.aspspName}</Text>
              {getStatusTag(connection.status, connection.isActive)}
            </Space>

            {connection.accounts && connection.accounts.length > 0 && (
              <div style={{ marginLeft: 22, marginTop: 8 }}>
                {connection.accounts.map((acc) => (
                  <div key={acc.accountId} style={{ marginBottom: 4, display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <Text>{acc.name || acc.iban}</Text>
                    {acc.linkedAccount ? (
                      <>
                        <Tag icon={<CheckCircleOutlined />} color="success">
                          Koblet til {acc.linkedAccount.accountNumber} {acc.linkedAccount.name}
                        </Tag>
                        {acc.importFromDate && (
                          <Text type="secondary" style={{ fontSize: 12 }}>
                            (fra {formatDate(acc.importFromDate)})
                          </Text>
                        )}
                        {canLink && (
                          <Button
                            size="small"
                            type="link"
                            icon={<LinkOutlined />}
                            onClick={() => onLinkAccount(connection.id, acc)}
                          >
                            Ændr
                          </Button>
                        )}
                      </>
                    ) : (
                      <>
                        <Tag color="warning">Ikke koblet</Tag>
                        {canLink && (
                          <Button
                            size="small"
                            type="link"
                            icon={<LinkOutlined />}
                            onClick={() => onLinkAccount(connection.id, acc)}
                          >
                            Kobl til konto
                          </Button>
                        )}
                      </>
                    )}
                  </div>
                ))}
              </div>
            )}

            {connection.validUntil && connection.isActive && (
              <Text type="secondary" style={{ marginLeft: 22 }}>
                Gyldig til: {formatDate(connection.validUntil)}
              </Text>
            )}

            {connection.failureReason && (
              <Text type="danger" style={{ marginLeft: 22 }}>
                <ExclamationCircleOutlined /> {connection.failureReason}
              </Text>
            )}

            <Text type="secondary" style={{ marginLeft: 22, fontSize: 12 }}>
              Oprettet: {formatDate(connection.createdAt)}
            </Text>
          </Space>
        </Col>
        <Col>
          <Space>
            {canReconnect && (
              <Button
                size="small"
                type="primary"
                loading={isReconnecting}
                icon={<ReloadOutlined />}
                onClick={() => onReconnect(connection.id)}
              >
                Genopret
              </Button>
            )}
            {canDisconnect && (
              <Popconfirm
                title={connection.status === 'established' ? 'Afbryd bankforbindelse?' : 'Fjern bankforbindelse?'}
                description={connection.status === 'established'
                  ? 'Du vil ikke længere modtage transaktioner fra denne konto.'
                  : 'Forbindelsen vil blive fjernet fra listen.'}
                onConfirm={() => onDisconnect(connection.id)}
                okText={connection.status === 'established' ? 'Afbryd' : 'Fjern'}
                cancelText="Annuller"
                okButtonProps={{ danger: true }}
              >
                <Button
                  size="small"
                  danger
                  loading={isDisconnecting}
                  icon={<DisconnectOutlined />}
                >
                  {connection.status === 'established' ? 'Afbryd' : 'Fjern'}
                </Button>
              </Popconfirm>
            )}
            {canArchive && (
              <Popconfirm
                title="Arkiver bankforbindelse?"
                description="Forbindelsen vil blive skjult fra listen."
                onConfirm={() => onArchive(connection.id)}
                okText="Arkiver"
                cancelText="Annuller"
              >
                <Button
                  size="small"
                  loading={isArchiving}
                  icon={<InboxOutlined />}
                >
                  Arkiver
                </Button>
              </Popconfirm>
            )}
          </Space>
        </Col>
      </Row>
    </Card>
  );
}
