import { mdiDownload, mdiFileUploadOutline, mdiHomeCity } from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import React, { ReactElement, useMemo, useState } from 'react';

import BaseButton from '../components/BaseButton';
import CardBox from '../components/CardBox';
import DragDropFilePicker from '../components/DragDropFilePicker';
import SectionMain from '../components/SectionMain';
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
import { getPageTitle } from '../config';
import { portfolioWorkbookSheets } from '../helpers/portfolioWorkbookSheets';
import { hasPermission } from '../helpers/userPermissions';
import LayoutAuthenticated from '../layouts/Authenticated';
import { useAppSelector } from '../stores/hooks';

type ImportSummary = Record<string, { created: number; reused: number }>;

type ImportResponse = {
  workbook: {
    fileName: string;
    sheets: Array<{
      key: string;
      name: string;
      rows: number;
    }>;
  };
  summary: ImportSummary;
};

const createPermissions = [
  'CREATE_TENANTS',
  'CREATE_ORGANIZATIONS',
  'CREATE_PROPERTIES',
  'CREATE_UNIT_TYPES',
  'CREATE_UNITS',
];

const summaryLabels: Record<string, string> = {
  tenants: 'Tenants',
  organizations: 'Organizations',
  properties: 'Properties',
  unit_types: 'Unit Types',
  units: 'Units',
};

const PortfolioImportPage = () => {
  const { currentUser } = useAppSelector((state) => state.auth);
  const canImportWorkbook = Boolean(currentUser?.app_role?.globalAccess || (currentUser && hasPermission(currentUser, createPermissions)));

  const [workbookFile, setWorkbookFile] = useState<File | null>(null);
  const [isDownloadingTemplate, setIsDownloadingTemplate] = useState(false);
  const [isImporting, setIsImporting] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');
  const [successMessage, setSuccessMessage] = useState('');
  const [importResult, setImportResult] = useState<ImportResponse | null>(null);

  const workbookSummary = useMemo(() => {
    if (!importResult?.summary) {
      return [];
    }

    return Object.entries(importResult.summary).filter(([, value]) => value.created > 0 || value.reused > 0);
  }, [importResult]);

  const downloadTemplate = async () => {
    try {
      setIsDownloadingTemplate(true);
      setErrorMessage('');

      const response = await axios.get('/corporate-stay-portal/portfolio-import-template', {
        responseType: 'blob',
      });

      const blob = new Blob([response.data], {
        type:
          response.headers['content-type'] ||
          'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
      });

      const link = document.createElement('a');
      link.href = window.URL.createObjectURL(blob);
      link.download = 'portfolio-import-template.xlsx';
      link.click();
      window.URL.revokeObjectURL(link.href);
    } catch (error: any) {
      setErrorMessage(error?.response?.data || 'Failed to download the workbook template.');
    } finally {
      setIsDownloadingTemplate(false);
    }
  };

  const submitWorkbook = async () => {
    if (!workbookFile || !canImportWorkbook) {
      return;
    }

    try {
      setIsImporting(true);
      setErrorMessage('');
      setSuccessMessage('');
      setImportResult(null);

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

      const response = await axios.post<ImportResponse>('/corporate-stay-portal/portfolio-import', formData, {
        headers: {
          'Content-Type': 'multipart/form-data',
        },
      });

      setImportResult(response.data);
      setSuccessMessage(`Workbook imported successfully: ${response.data.workbook.fileName}`);
      setWorkbookFile(null);
    } catch (error: any) {
      setErrorMessage(error?.response?.data || 'Workbook import failed.');
    } finally {
      setIsImporting(false);
    }
  };

  return (
    <>
      <Head>
        <title>{getPageTitle('Portfolio Import Center')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton icon={mdiHomeCity} title='Portfolio Import Center' main>
          {''}
        </SectionTitleLineWithButton>

        <CardBox className='mb-6'>
          <div className='space-y-4'>
            <div>
              <h2 className='text-lg font-semibold text-gray-900 dark:text-slate-100'>One workbook for portfolio onboarding</h2>
              <p className='mt-2 text-sm text-gray-600 dark:text-slate-300'>
                Upload a single Excel workbook to create linked tenants, organizations, properties, unit types, and units in dependency order.
                Existing records are reused when the workbook references a matching ID or business key.
              </p>
              <p className='mt-2 text-sm text-gray-600 dark:text-slate-300'>
                This v1 workbook flow covers portfolio setup sheets only. Negotiated rates stay on their current flow for now.
              </p>
            </div>

            {!canImportWorkbook && (
              <div className='rounded-xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-900 dark:border-amber-500/40 dark:bg-amber-500/10 dark:text-amber-100'>
                You can review the template, but uploading requires at least one of these permissions: {createPermissions.join(', ')}.
              </div>
            )}

            {errorMessage && (
              <div className='rounded-xl border border-red-200 bg-red-50 px-4 py-3 text-sm text-red-700 dark:border-red-500/40 dark:bg-red-500/10 dark:text-red-100'>
                {errorMessage}
              </div>
            )}

            {successMessage && (
              <div className='rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm text-emerald-700 dark:border-emerald-500/40 dark:bg-emerald-500/10 dark:text-emerald-100'>
                {successMessage}
              </div>
            )}

            <div className='flex flex-wrap gap-3'>
              <BaseButton
                color='info'
                icon={mdiDownload}
                label={isDownloadingTemplate ? 'Downloading...' : 'Download template'}
                onClick={downloadTemplate}
                disabled={isDownloadingTemplate}
              />
              <BaseButton
                color='info'
                icon={mdiFileUploadOutline}
                label={isImporting ? 'Importing workbook...' : 'Import workbook'}
                onClick={submitWorkbook}
                disabled={!workbookFile || !canImportWorkbook || isImporting}
              />
            </div>

            <DragDropFilePicker file={workbookFile} setFile={setWorkbookFile} formats={'.xlsx,.xls'} />
          </div>
        </CardBox>

        {importResult && (
          <CardBox className='mb-6'>
            <div className='space-y-4'>
              <div>
                <h3 className='text-base font-semibold text-gray-900 dark:text-slate-100'>Latest import summary</h3>
                <p className='mt-1 text-sm text-gray-600 dark:text-slate-300'>
                  Processed sheets:{' '}
                  {importResult.workbook.sheets.map((sheet) => `${sheet.name} (${sheet.rows})`).join(', ')}
                </p>
              </div>
              <div className='grid gap-4 md:grid-cols-2 xl:grid-cols-5'>
                {workbookSummary.map(([key, value]) => (
                  <div key={key} className='rounded-xl border border-gray-200 px-4 py-3 dark:border-slate-700'>
                    <div className='text-sm font-semibold text-gray-900 dark:text-slate-100'>{summaryLabels[key] || key}</div>
                    <div className='mt-2 text-sm text-gray-600 dark:text-slate-300'>Created: {value.created}</div>
                    <div className='text-sm text-gray-600 dark:text-slate-300'>Reused: {value.reused}</div>
                  </div>
                ))}
              </div>
            </div>
          </CardBox>
        )}

        <div className='grid gap-6 xl:grid-cols-2'>
          {portfolioWorkbookSheets.map((sheet) => {
            const exampleCsvRow = sheet.columns.map((column) => sheet.exampleRow[column] ?? '').join('\t');

            return (
              <CardBox key={sheet.key} className='h-full'>
                <div className='space-y-4'>
                  <div>
                    <h3 className='text-base font-semibold uppercase tracking-wide text-gray-900 dark:text-slate-100'>{sheet.label}</h3>
                    <p className='mt-2 text-sm text-gray-600 dark:text-slate-300'>{sheet.description}</p>
                  </div>

                  <div>
                    <div className='text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-slate-400'>Required columns</div>
                    <p className='mt-1 text-sm text-gray-700 dark:text-slate-200'>{sheet.requiredColumns.join(', ')}</p>
                  </div>

                  <div>
                    <div className='text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-slate-400'>All columns</div>
                    <p className='mt-1 break-words text-sm text-gray-700 dark:text-slate-200'>{sheet.columns.join(', ')}</p>
                  </div>

                  <div>
                    <div className='text-xs font-semibold uppercase tracking-wide text-gray-500 dark:text-slate-400'>Example row</div>
                    <pre className='mt-2 overflow-x-auto rounded-xl bg-slate-900 px-4 py-3 text-xs text-slate-100'>
{`${sheet.columns.join('\t')}
${exampleCsvRow}`}
                    </pre>
                  </div>
                </div>
              </CardBox>
            );
          })}
        </div>
      </SectionMain>
    </>
  );
};

PortfolioImportPage.getLayout = function getLayout(page: ReactElement) {
  return <LayoutAuthenticated>{page}</LayoutAuthenticated>;
};

export default PortfolioImportPage;
