import * as icon from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import React, { ReactElement, useEffect, useMemo, useRef, useState } from 'react';

import BaseIcon from '../components/BaseIcon';
import CardBox from '../components/CardBox';
import LayoutAuthenticated from '../layouts/Authenticated';
import LoadingSpinner from '../components/LoadingSpinner';
import SectionMain from '../components/SectionMain';
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
import { getPageTitle } from '../config';

type Provider = {
  key: string;
  name: string;
  category: string;
  description: string;
  configured: boolean;
  missingEnv: string[];
  actions: string[];
  docsUrl: string;
};

type IntegrationStatus = {
  headline: string;
  strategy: string;
  providers: Provider[];
};

type ActionResult = {
  type: 'success' | 'error';
  title: string;
  message: string;
  payload?: unknown;
};

const demoSampleRequestId = '79200000-0000-4000-8000-000000000002';

const providerIcons: Record<string, string> = {
  csv: icon.mdiFileDocumentOutline,
  google_sheets: icon.mdiFileDocumentOutline,
  stripe: icon.mdiCashMultiple,
  hubspot: icon.mdiAccountGroup,
  quickbooks: icon.mdiFinance,
  doordash: icon.mdiTruckDelivery,
  shippo: icon.mdiTruckDelivery,
};

const actionLabels: Record<string, string> = {
  csv: 'Export CSV',
  google_sheets: 'Push catalog',
  stripe: 'Create checkout',
  hubspot: 'Sync sample',
  quickbooks: 'Create invoice',
  doordash: 'DoorDash quote',
  shippo: 'Shippo rates',
};

const categories = [
  'Catalog operations',
  'Payments',
  'Sales ops',
  'Accounting',
  'Local delivery',
  'Carrier shipping',
];

const readErrorMessage = (error: unknown) => {
  if (axios.isAxiosError(error)) {
    if (typeof error.response?.data === 'string') {
      return error.response.data;
    }

    if (error.response?.data) {
      return JSON.stringify(error.response.data);
    }
  }

  if (error instanceof Error) {
    return error.message;
  }

  return 'Integration action failed.';
};

const stringifyPayload = (payload: unknown) => {
  if (!payload) {
    return '';
  }

  return JSON.stringify(payload, null, 2);
};

const IntegrationsPage = () => {
  const [status, setStatus] = useState<IntegrationStatus | null>(null);
  const [isLoading, setIsLoading] = useState(true);
  const [activeAction, setActiveAction] = useState('');
  const [actionResult, setActionResult] = useState<ActionResult | null>(null);
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const configuredCount = useMemo(() => {
    return (status?.providers || []).filter((provider) => provider.configured)
      .length;
  }, [status?.providers]);

  const catalogProvider = status?.providers.find(
    (provider) => provider.key === 'csv',
  );

  const loadStatus = async () => {
    setIsLoading(true);
    const { data } = await axios.get('/integrations');
    setStatus(data);
    setIsLoading(false);
  };

  useEffect(() => {
    void loadStatus();
  }, []);

  const runAction = async (providerKey: string) => {
    setActiveAction(providerKey);
    setActionResult(null);

    try {
      if (providerKey === 'csv') {
        const response = await axios.get('/integrations/csv/products', {
          responseType: 'blob',
        });
        const url = window.URL.createObjectURL(
          new Blob([response.data], { type: 'text/csv' }),
        );
        const link = document.createElement('a');
        link.href = url;
        link.download = 'northstar-product-catalog.csv';
        link.click();
        window.URL.revokeObjectURL(url);
        setActionResult({
          type: 'success',
          title: 'CSV export ready',
          message: 'Product catalog CSV was generated from the live catalog.',
        });
        return;
      }

      if (providerKey === 'google_sheets') {
        const { data } = await axios.post(
          '/integrations/google-sheets/export-products',
        );
        setActionResult({
          type: 'success',
          title: 'Google Sheets export complete',
          message: `Exported ${data.rowsExported} catalog rows.`,
          payload: data,
        });
        return;
      }

      if (providerKey === 'stripe') {
        const { data } = await axios.post('/integrations/stripe/checkout', {
          amountCents: 12500,
          currency: 'usd',
          orderLabel: 'Northstar demo purchase order',
          successUrl: window.location.href,
          cancelUrl: window.location.href,
        });
        setActionResult({
          type: 'success',
          title: 'Stripe checkout created',
          message: data.url || data.sessionId,
          payload: data,
        });
        return;
      }

      if (providerKey === 'hubspot') {
        const { data } = await axios.post(
          '/integrations/hubspot/sync-sample-request',
          { sampleRequestId: demoSampleRequestId },
        );
        setActionResult({
          type: 'success',
          title: 'HubSpot sample follow-up synced',
          message: `Deal ${data.dealId} was created from the sample request.`,
          payload: data,
        });
        return;
      }

      if (providerKey === 'quickbooks') {
        const { data } = await axios.post(
          '/integrations/quickbooks/create-invoice',
          {
            amount: 125,
            description: 'Northstar demo purchase order',
          },
        );
        setActionResult({
          type: 'success',
          title: 'QuickBooks invoice created',
          message: `Invoice ${data.invoiceId || data.docNumber} was created.`,
          payload: data,
        });
        return;
      }

      if (providerKey === 'doordash') {
        const { data } = await axios.post('/integrations/delivery/create-quote', {
          provider: 'doordash',
          dropoffAddress: '500 W Madison St, Chicago, IL 60661',
          dropoffBusinessName: 'Cedar & Sage Production Kitchen',
          orderValue: 12500,
        });
        setActionResult({
          type: 'success',
          title: 'DoorDash quote created',
          message: 'Local delivery quote returned from DoorDash Drive.',
          payload: data,
        });
        return;
      }

      if (providerKey === 'shippo') {
        const { data } = await axios.post('/integrations/delivery/create-quote', {
          provider: 'shippo',
        });
        setActionResult({
          type: 'success',
          title: 'Shippo rates created',
          message: `${data.rates?.length || 0} carrier rates returned.`,
          payload: data,
        });
      }
    } catch (error) {
      setActionResult({
        type: 'error',
        title: 'Integration action failed',
        message: readErrorMessage(error),
      });
    } finally {
      setActiveAction('');
    }
  };

  const importCsv = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];

    if (!file) {
      return;
    }

    setActiveAction('csv-import');
    setActionResult(null);

    try {
      const formData = new FormData();
      formData.append('file', file);
      formData.append('filename', file.name);

      await axios.post('/products/bulk-import', formData, {
        headers: { 'Content-Type': 'multipart/form-data' },
      });
      setActionResult({
        type: 'success',
        title: 'CSV import complete',
        message: `${file.name} was imported into the product catalog.`,
      });
    } catch (error) {
      setActionResult({
        type: 'error',
        title: 'CSV import failed',
        message: readErrorMessage(error),
      });
    } finally {
      event.target.value = '';
      setActiveAction('');
    }
  };

  return (
    <>
      <Head>
        <title>{getPageTitle('Integration Center')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={icon.mdiLinkVariant}
          title='Integration Center'
          main
        />

        {isLoading && (
          <CardBox className='mb-6 flex h-56 items-center justify-center border border-slate-200 bg-white shadow-sm'>
            <LoadingSpinner />
          </CardBox>
        )}

        {!isLoading && status && (
          <>
            <CardBox className='mb-6 overflow-hidden border border-slate-200 bg-white shadow-sm'>
              <div className='grid gap-0 xl:grid-cols-[minmax(0,1fr)_360px]'>
                <div className='p-6'>
                  <p className='text-xs font-semibold uppercase tracking-[0.22em] text-emerald-700'>
                    Connected foodservice stack
                  </p>
                  <h1 className='mt-3 text-3xl font-semibold text-slate-950'>
                    Integrate ordering, accounting, CRM, payments, and delivery
                  </h1>
                  <p className='mt-3 max-w-4xl text-sm leading-7 text-slate-600'>
                    {status.strategy} This template ships with working CSV
                    import/export and real adapter endpoints for Google Sheets,
                    Stripe, HubSpot, QuickBooks, DoorDash Drive, and Shippo.
                  </p>
                </div>
                <div className='bg-slate-950 p-6 text-white'>
                  <p className='text-xs font-semibold uppercase tracking-[0.18em] text-emerald-300'>
                    Configuration
                  </p>
                  <p className='mt-3 text-3xl font-semibold'>
                    {configuredCount}/{status.providers.length}
                  </p>
                  <p className='mt-2 text-sm leading-6 text-slate-300'>
                    Providers ready with the required environment variables.
                    Missing keys are shown on each connector card.
                  </p>
                </div>
              </div>
            </CardBox>

            {actionResult && (
              <CardBox
                className={`mb-6 border shadow-sm ${
                  actionResult.type === 'success'
                    ? 'border-emerald-200 bg-emerald-50'
                    : 'border-rose-200 bg-rose-50'
                }`}
              >
                <div className='flex items-start gap-3'>
                  <BaseIcon
                    path={
                      actionResult.type === 'success'
                        ? icon.mdiCheckCircleOutline
                        : icon.mdiAlertCircleOutline
                    }
                    className={
                      actionResult.type === 'success'
                        ? 'text-emerald-700'
                        : 'text-rose-700'
                    }
                  />
                  <div className='min-w-0'>
                    <h2 className='font-semibold text-slate-950'>
                      {actionResult.title}
                    </h2>
                    <p className='mt-1 text-sm leading-6 text-slate-700'>
                      {actionResult.message}
                    </p>
                    {actionResult.payload && (
                      <pre className='mt-4 max-h-72 overflow-auto rounded-xl bg-slate-950 p-4 text-xs text-slate-100'>
                        {stringifyPayload(actionResult.payload)}
                      </pre>
                    )}
                  </div>
                </div>
              </CardBox>
            )}

            <div className='mb-6 grid gap-4 md:grid-cols-2 xl:grid-cols-3'>
              {categories.map((category) => (
                <div
                  key={category}
                  className='rounded-2xl border border-slate-200 bg-white p-4 shadow-sm'
                >
                  <p className='text-xs font-semibold uppercase tracking-[0.16em] text-slate-400'>
                    {category}
                  </p>
                  <p className='mt-2 text-2xl font-semibold text-slate-950'>
                    {
                      status.providers.filter(
                        (provider) => provider.category === category,
                      ).length
                    }
                  </p>
                </div>
              ))}
            </div>

            <div className='grid gap-5 xl:grid-cols-2'>
              {status.providers.map((provider) => (
                <CardBox
                  key={provider.key}
                  className='border border-slate-200 bg-white shadow-sm'
                >
                  <div className='flex flex-col gap-4 sm:flex-row sm:items-start sm:justify-between'>
                    <div className='flex items-start gap-4'>
                      <span className='flex h-12 w-12 items-center justify-center rounded-2xl bg-emerald-50 text-emerald-700'>
                        <BaseIcon
                          path={providerIcons[provider.key] || icon.mdiApi}
                        />
                      </span>
                      <div>
                        <p className='text-xs font-semibold uppercase tracking-[0.16em] text-slate-400'>
                          {provider.category}
                        </p>
                        <h2 className='mt-1 text-xl font-semibold text-slate-950'>
                          {provider.name}
                        </h2>
                      </div>
                    </div>
                    <span
                      className={`inline-flex rounded-full border px-3 py-1 text-xs font-bold ${
                        provider.configured
                          ? 'border-emerald-200 bg-emerald-50 text-emerald-800'
                          : 'border-amber-200 bg-amber-50 text-amber-800'
                      }`}
                    >
                      {provider.configured ? 'Ready' : 'Needs config'}
                    </span>
                  </div>

                  <p className='mt-4 text-sm leading-7 text-slate-600'>
                    {provider.description}
                  </p>

                  <div className='mt-4 rounded-xl bg-slate-50 p-4'>
                    <p className='text-xs font-semibold uppercase tracking-[0.16em] text-slate-400'>
                      Actions
                    </p>
                    <div className='mt-3 flex flex-wrap gap-2'>
                      {provider.actions.map((action) => (
                        <span
                          key={action}
                          className='rounded-full border border-slate-200 bg-white px-3 py-1 text-xs font-semibold text-slate-700'
                        >
                          {action}
                        </span>
                      ))}
                    </div>
                  </div>

                  {!provider.configured && provider.missingEnv.length > 0 && (
                    <div className='mt-4 rounded-xl border border-amber-200 bg-amber-50 p-4'>
                      <p className='text-xs font-semibold uppercase tracking-[0.16em] text-amber-700'>
                        Missing env
                      </p>
                      <p className='mt-2 break-words text-sm font-semibold text-amber-900'>
                        {provider.missingEnv.join(', ')}
                      </p>
                    </div>
                  )}

                  <div className='mt-5 flex flex-wrap items-center gap-2'>
                    <button
                      type='button'
                      onClick={() => void runAction(provider.key)}
                      className='inline-flex h-10 items-center rounded-xl bg-slate-950 px-4 text-sm font-semibold text-white hover:bg-slate-800'
                    >
                      {activeAction === provider.key ? (
                        <span className='flex items-center gap-2'>
                          <span className='h-4 w-4 animate-spin rounded-full border-2 border-white/30 border-t-white' />
                          Running
                        </span>
                      ) : (
                        actionLabels[provider.key] || 'Run action'
                      )}
                    </button>

                    {provider.key === 'csv' && (
                      <>
                        <button
                          type='button'
                          onClick={() => fileInputRef.current?.click()}
                          className='inline-flex h-10 items-center rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 hover:bg-slate-50'
                        >
                          {activeAction === 'csv-import'
                            ? 'Importing'
                            : 'Import CSV'}
                        </button>
                        <input
                          ref={fileInputRef}
                          type='file'
                          accept='.csv'
                          className='hidden'
                          onChange={importCsv}
                        />
                      </>
                    )}

                    <a
                      href={provider.docsUrl}
                      target='_blank'
                      rel='noreferrer'
                      className='inline-flex h-10 items-center rounded-xl border border-slate-200 bg-white px-4 text-sm font-semibold text-slate-700 hover:bg-slate-50'
                    >
                      Docs
                    </a>
                  </div>
                </CardBox>
              ))}
            </div>

            {catalogProvider && (
              <div className='mt-6 rounded-2xl border border-slate-800 bg-slate-950 p-6 text-white shadow-sm'>
                <p className='text-xs font-semibold uppercase tracking-[0.2em] text-emerald-300'>
                  Template blueprint
                </p>
                <h2 className='mt-3 text-2xl font-semibold'>
                  Integration flow built into the B2B supplier portal
                </h2>
                <div className='mt-5 grid gap-3 md:grid-cols-3'>
                  {[
                    'Catalog and price sheets sync into Products and Price Lists.',
                    'Buyer activity becomes CRM follow-up and accounting documents.',
                    'Approved orders move into payment and delivery workflows.',
                  ].map((item, index) => (
                    <div
                      key={item}
                      className='rounded-xl border border-white/10 bg-white/5 p-4'
                    >
                      <span className='flex h-8 w-8 items-center justify-center rounded-full bg-emerald-400 text-sm font-bold text-slate-950'>
                        {index + 1}
                      </span>
                      <p className='mt-3 text-sm font-semibold leading-6 text-slate-100'>
                        {item}
                      </p>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </>
        )}
      </SectionMain>
    </>
  );
};

IntegrationsPage.getLayout = function getLayout(page: ReactElement) {
  return (
    <LayoutAuthenticated permission='READ_API_DOCS'>{page}</LayoutAuthenticated>
  );
};

export default IntegrationsPage;
