import { mdiCog, mdiRefresh } from '@mdi/js';
import axios from 'axios';
import Head from 'next/head';
import Link from 'next/link';
import { useRouter } from 'next/router';
import React, { ReactElement, useCallback, useEffect, useState } from 'react';
import BaseButton from '../components/BaseButton';
import CardBox from '../components/CardBox';
import LayoutAuthenticated from '../layouts/Authenticated';
import SectionMain from '../components/SectionMain';
import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
import { getPageTitle } from '../config';
import { logger } from '../lib/logger';

type ProjectElementDefault = {
  id: string;
  element_type: string;
  name?: string;
  sort_order?: number;
  settings_json?: string | Record<string, unknown>;
  source_element_id?: string;
  snapshot_version?: number;
  projectId: string;
};

type Project = {
  id: string;
  name?: string;
  slug?: string;
};

const toHumanLabel = (value: string) =>
  String(value || '')
    .split('_')
    .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
    .join(' ');

const ProjectElementDefaultsPage = () => {
  const router = useRouter();
  const { projectId } = router.query;

  const [rows, setRows] = useState<ProjectElementDefault[]>([]);
  const [project, setProject] = useState<Project | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  const loadProject = useCallback(async () => {
    if (!projectId || typeof projectId !== 'string') return;
    try {
      const response = await axios.get(`/projects/${projectId}`);
      setProject(response?.data || null);
    } catch (error: any) {
      logger.error('Failed to load project:', error);
    }
  }, [projectId]);

  const loadRows = useCallback(async () => {
    if (!projectId || typeof projectId !== 'string') return;
    try {
      setIsLoading(true);
      setErrorMessage('');

      const response = await axios.get(
        `/project-element-defaults?projectId=${projectId}&limit=1000&page=0&sort=asc&field=sort_order`,
      );

      const nextRows: ProjectElementDefault[] = Array.isArray(
        response?.data?.rows,
      )
        ? response.data.rows
        : [];
      setRows(nextRows);
    } catch (error: any) {
      const message =
        error?.response?.data?.message ||
        error?.message ||
        'Failed to load project element defaults.';
      logger.error(
        'Failed to load project element defaults:',
        error instanceof Error ? error : { error },
      );
      setErrorMessage(message);
      setRows([]);
    } finally {
      setIsLoading(false);
    }
  }, [projectId]);

  useEffect(() => {
    if (projectId) {
      loadProject();
      loadRows();
    }
  }, [projectId, loadProject, loadRows]);

  if (!projectId) {
    return (
      <>
        <Head>
          <title>{getPageTitle('Project Element Defaults')}</title>
        </Head>
        <SectionMain>
          <SectionTitleLineWithButton
            icon={mdiCog}
            title='Project Element Defaults'
            main
          >
            {''}
          </SectionTitleLineWithButton>
          <CardBox>
            <p className='text-sm text-gray-500'>
              No project selected. Please select a project from the URL query
              parameter.
            </p>
          </CardBox>
        </SectionMain>
      </>
    );
  }

  return (
    <>
      <Head>
        <title>{getPageTitle('Project Element Defaults')}</title>
      </Head>
      <SectionMain>
        <SectionTitleLineWithButton
          icon={mdiCog}
          title={`Element Defaults: ${project?.name || 'Loading...'}`}
          main
        >
          <BaseButton
            color='lightDark'
            label='Refresh'
            icon={mdiRefresh}
            onClick={loadRows}
            disabled={isLoading}
          />
        </SectionTitleLineWithButton>

        <CardBox>
          {isLoading ? (
            <p className='text-sm text-gray-500'>
              Loading project element defaults...
            </p>
          ) : errorMessage ? (
            <p className='text-sm text-red-600'>{errorMessage}</p>
          ) : rows.length === 0 ? (
            <div className='space-y-2'>
              <p className='text-sm text-gray-500'>
                No element defaults found for this project.
              </p>
              <p className='text-xs text-gray-400'>
                Element defaults are automatically created when a project is
                created. If this is an older project, the defaults may not have
                been snapshotted yet.
              </p>
            </div>
          ) : (
            <div className='space-y-2'>
              <p className='mb-4 text-xs text-gray-500'>
                These settings control the default appearance of new elements
                created in the constructor. Changes here will only affect new
                elements, not existing ones.
              </p>
              {rows.map((item) => (
                <Link
                  key={item.id}
                  href={`/project-element-defaults/${item.id}?projectId=${projectId}`}
                  className='block rounded border border-gray-200 px-3 py-2 hover:bg-gray-50 dark:border-dark-700 dark:hover:bg-dark-800'
                >
                  <p className='text-sm font-semibold'>
                    {item.name || toHumanLabel(item.element_type)}
                  </p>
                  <p className='text-xs text-gray-500'>
                    {toHumanLabel(item.element_type)} • Order{' '}
                    {Number(item.sort_order || 0)} • Version{' '}
                    {item.snapshot_version || 1}
                    {item.source_element_id && ' • Synced with global'}
                  </p>
                </Link>
              ))}
            </div>
          )}
        </CardBox>
      </SectionMain>
    </>
  );
};

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

export default ProjectElementDefaultsPage;
