import React from 'react';
import {
    ABACUS_ACTION_STATUSES,
    EMPTY_CHAR,
} from '@theorchard/accounting-apps-shared';
import {
    Button,
    Divider,
    FullscreenModal,
    GlyphButton,
    Label,
    Metadata,
    PageHeader,
    Pill,
    Section,
    SkeletonLoader,
    Status,
    Tag,
} from '@theorchard/suite-components';
import { BrandIcon } from '@theorchard/suite-icons';
import { Page } from '@theorchard/suite-frontend';
import {
    useGetPayeeCollaboratorContact,
    useGetPayeeDetailsById,
} from 'src/apollo/queries/payees';
import { smartFormatter } from 'src/utils/amount-helpers';

const CLASS_NAME = 'PayeeDetailsModal';

const BANK_FIELD_LABELS: Record<string, string> = {
    AccountName: 'Account Holder Name',
    BankName: 'Bank Name',
    Swift: 'SWIFT/BIC',
    IBAN: 'IBAN',
    BIC: 'BIC',
};

const BANK_FIELD_ORDER = ['AccountName', 'BankName', 'Swift', 'IBAN', 'BIC'];

export type BankDetails = {
    contact?: {
        firstName?: string | null;
        lastName?: string | null;
        email?: string | null;
    } | null;
    payoutMethod: {
        country?: string | null;
        currency?: string | null;
        bankFieldDetails: { name: string; value: string }[];
    };
};

interface Props {
    collaboratorId: string;
    payeeId: string;
    isOpen: boolean;
    onRequestClose: () => void;
    onReject?: () => void;
    showReject: boolean;
}

const Col: React.FC<{
    label: string;
    text: string | null;
    loading?: boolean;
}> = ({ label, loading, text }) => (
    <Page.Col sm={12} md={4}>
        <Label text={label} />
        {loading ? <SkeletonLoader /> : <span>{text ?? ''}</span>}
    </Page.Col>
);

const PayeeDetailsModal: React.FC<Props> = ({
    collaboratorId,
    payeeId,
    isOpen,
    onRequestClose,
    onReject,
    showReject,
}) => {
    const {
        contact: identityContact,
        collaborator,
        loading: contactLoading,
    } = useGetPayeeCollaboratorContact({ collaboratorId });

    const {
        payee: payeeHeaderData,
        bankDetails,
        loading: bankLoading,
    } = useGetPayeeDetailsById({
        payeeId,
    });

    const contact = bankDetails?.contact?.email
        ? bankDetails?.contact
        : identityContact;
    const currentBalance = collaborator?.currentBalance;

    const bankFields = bankDetails
        ? BANK_FIELD_ORDER.reduce<{ label: string; value: string }[]>(
              (acc, key) => {
                  const field = bankDetails.payoutMethod.bankFieldDetails.find(
                      f => f.name === key
                  );
                  if (field) {
                      acc.push({
                          label: BANK_FIELD_LABELS[key],
                          value: field.value,
                      });
                  }
                  return acc;
              },
              []
          )
        : [];

    const determinePayeeStatus = (
        bankingState: { actionStatus: string; message?: string | null },
        kycNotification: { fileUploadLink: string | null } | null = null
    ) => {
        type Variant = React.ComponentProps<typeof Status>['variant'];
        // eslint-disable-next-line prefer-const
        let [variant, message] = ((): [Variant, string | null] => {
            switch (bankingState.actionStatus) {
                case ABACUS_ACTION_STATUSES.INIT:
                    return ['neutral', 'Details not submitted'];
                case ABACUS_ACTION_STATUSES.RUNNING:
                    return ['warning', bankingState.message ?? null];
                case ABACUS_ACTION_STATUSES.COMPLETE:
                    return ['success', 'Eligible for payment'];
                case ABACUS_ACTION_STATUSES.REJECTED:
                    return ['error', 'Rejected'];
                default:
                    return ['neutral', null];
            }
        })();

        if (kycNotification && kycNotification.fileUploadLink) message = '';

        return (
            <Status
                className="PayeeManagement-payee-status"
                text={message ?? 'Unknown'}
                variant={variant}
                filled
            >
                {kycNotification && bankingState.message}
            </Status>
        );
    };

    const normalizedHeaderLabel = (() => {
        const fetchedLabel =
            payeeHeaderData?.payeeCollaborator?.collaborator?.label;

        if (!fetchedLabel) return null;
        if (fetchedLabel.__typename === 'Vendor') return fetchedLabel;
        if (fetchedLabel.__typename === 'Subaccount') {
            return {
                ...fetchedLabel,
                ...fetchedLabel.vendor,
            };
        }

        return null;
    })();

    const effectiveBankingState = payeeHeaderData?.actionStates?.[0] ?? null;

    const effectiveKycNotification =
        payeeHeaderData?.payeeKycNotification ?? null;

    const renderAccountPill = () => {
        if (!normalizedHeaderLabel) return null;

        const label = normalizedHeaderLabel;
        return (
            <Pill
                text={label.name || ''}
                brand={label.companyBrand?.name || ''}
                popoverOptions={{
                    id: 'PillPopover',
                    content: (
                        <Section level="top">
                            <Section.Header>
                                <div>
                                    <div className="PayeeManagement-account-pill-header">
                                        <BrandIcon
                                            brand={
                                                label.companyBrand?.name || ''
                                            }
                                            size={24}
                                        />
                                        <Section.Title>
                                            {label.name || EMPTY_CHAR}
                                            <span className="PayeeManagement-subtext">
                                                <span> {'\u2022'} </span>
                                                {label.id?.vendorId ||
                                                    EMPTY_CHAR}
                                            </span>
                                        </Section.Title>
                                    </div>
                                    <div className="PayeeManagement-secondary-text">
                                        Account
                                    </div>
                                </div>
                            </Section.Header>
                            <Section.Body>
                                <Section level="nested">
                                    <Section.Body>
                                        <div className="PayeeManagement-account-pill-details">
                                            <Metadata label="Parent Company">
                                                <BrandIcon
                                                    brand={
                                                        label.companyBrand
                                                            ?.name || ''
                                                    }
                                                    size="16"
                                                />
                                                <span>
                                                    {label.companyBrand?.name ||
                                                        EMPTY_CHAR}
                                                </span>
                                            </Metadata>
                                            <Metadata label="Service Tier">
                                                <span>
                                                    {label.serviceTier
                                                        ?.displayName ||
                                                        EMPTY_CHAR}
                                                </span>
                                            </Metadata>
                                        </div>
                                    </Section.Body>
                                </Section>
                            </Section.Body>
                        </Section>
                    ),
                }}
            />
        );
    };

    const renderFileUploadLink = () => {
        const fileUploadLink = effectiveKycNotification?.fileUploadLink;
        if (!fileUploadLink) return null;

        return (
            <GlyphButton
                name="externalLink"
                tooltip="Payoneer KYC Link"
                onClick={() => window.open(fileUploadLink, '_blank')}
            />
        );
    };

    const canReject = !!onReject && !!showReject;

    const headerTitle =
        payeeHeaderData?.payeeName || collaborator?.name || EMPTY_CHAR;

    return (
        <FullscreenModal isOpen={isOpen} onRequestClose={onRequestClose}>
            <FullscreenModal.Header>
                <Button onClick={onRequestClose}>Cancel</Button>
            </FullscreenModal.Header>
            <FullscreenModal.Body>
                <PageHeader
                    sticky
                    variant="standalone"
                    topMetadata={{
                        left: ({ loading, defaultLoader }) =>
                            loading ? (
                                defaultLoader
                            ) : (
                                <Tag variant="category">Collaborator Payee</Tag>
                            ),
                        right: () => renderAccountPill(),
                    }}
                    mainContent={{
                        title: headerTitle,
                        subtitle: payeeId,
                        append: () =>
                            effectiveBankingState
                                ? determinePayeeStatus(
                                      effectiveBankingState,
                                      effectiveKycNotification
                                  )
                                : null,
                    }}
                    actions={() => (
                        <>
                            {renderFileUploadLink()}
                            {canReject && (
                                <Button variant="primary" onClick={onReject}>
                                    Reject
                                </Button>
                            )}
                        </>
                    )}
                />
                <Section className={CLASS_NAME}>
                    <Section.Body>
                        <Page.Grid>
                            <h4>Collaborator Details</h4>
                            <Col
                                label="Name"
                                text={collaborator?.name ?? 'Unknown'}
                                loading={contactLoading}
                            />
                            <Col
                                label="ID"
                                text={collaborator?.id ?? 'Unknown'}
                                loading={contactLoading}
                            />
                            <Col
                                label="Current Balance"
                                text={
                                    currentBalance
                                        ? smartFormatter(
                                              currentBalance.amount,
                                              currentBalance.currency
                                          )
                                        : 'Unknown'
                                }
                                loading={contactLoading}
                            />
                        </Page.Grid>
                        <Divider
                            className="d-block mt-4 mb-4"
                            direction="horizontal"
                            width={1}
                        />
                        <Page.Grid>
                            <h4>Contact Details</h4>
                            <Col
                                label="First Name"
                                text={contact?.firstName ?? 'Unknown'}
                                loading={contactLoading}
                            />
                            <Col
                                label="Last Name"
                                text={contact?.lastName ?? 'Unknown'}
                                loading={contactLoading}
                            />
                            <Col
                                label="Email"
                                text={contact?.email ?? 'Unknown'}
                                loading={contactLoading}
                            />
                        </Page.Grid>
                        {bankDetails && (
                            <>
                                <Divider
                                    className="d-block mt-4 mb-4"
                                    direction="horizontal"
                                    width={1}
                                />
                                <Page.Grid>
                                    <h4>Bank Details Submitted</h4>
                                    <Col
                                        label="Account Holder Name"
                                        text={
                                            `${bankDetails?.contact?.firstName ?? ''} ${bankDetails?.contact?.lastName ?? ''}`.trim() ||
                                            'Unknown'
                                        }
                                        loading={bankLoading}
                                    />
                                    <Col
                                        label="Bank Country"
                                        text={
                                            bankDetails?.payoutMethod.country ??
                                            'Unknown'
                                        }
                                        loading={bankLoading}
                                    />
                                    <Col
                                        label="Bank Currency"
                                        text={
                                            bankDetails?.payoutMethod
                                                .currency ?? 'Unknown'
                                        }
                                        loading={bankLoading}
                                    />
                                    {bankFields.map(({ label, value }) => (
                                        <Col
                                            key={label}
                                            label={label}
                                            text={value}
                                            loading={bankLoading}
                                        />
                                    ))}
                                </Page.Grid>
                            </>
                        )}
                    </Section.Body>
                </Section>
            </FullscreenModal.Body>
        </FullscreenModal>
    );
};

export default PayeeDetailsModal;
