import { Anchor, Card, Empty, Flex, Space, Tag, Typography } from 'antd';
import { createElement, useEffect, useMemo, useState } from 'react';
import type { LoadedSampleEntry, SampleEntry } from '../../../samples/registry';
import { resolveSampleEntries } from '../../../samples/registry';

const { Paragraph, Text, Title } = Typography;

export type ComponentSamplesLayoutProps = {
  entries: SampleEntry[];
  pathFilter?: string;
  excludeComponentIds?: string[];
  includeComponentIds?: string[];
};

export function ComponentSamplesLayout({
  entries,
  pathFilter = '/components/',
  excludeComponentIds = [],
  includeComponentIds = [],
}: ComponentSamplesLayoutProps) {
  const [sampleEntries, setSampleEntries] = useState<LoadedSampleEntry[]>([]);

  useEffect(() => {
    let mounted = true;

    void resolveSampleEntries(entries, pathFilter).then((loadedEntries) => {
      if (mounted) {
        setSampleEntries(loadedEntries);
      }
    });

    return () => {
      mounted = false;
    };
  }, [entries, pathFilter]);
  const groupedComponents = useMemo(() => {
    const excludedComponentIdSet = new Set(excludeComponentIds);
    const includedComponentIdSet = includeComponentIds.length ? new Set(includeComponentIds) : null;
    const componentMap = new Map<
      string,
      {
        componentId: string;
        title: string;
        description: string;
        category: string;
        baseSample?: (typeof sampleEntries)[number];
        pluginSamples: (typeof sampleEntries)[number][];
        featureSamples: (typeof sampleEntries)[number][];
      }
    >();

    sampleEntries.forEach((entry) => {
      if (excludedComponentIdSet.has(entry.sampleMeta.componentId)) {
        return;
      }

      if (includedComponentIdSet && !includedComponentIdSet.has(entry.sampleMeta.componentId)) {
        return;
      }

      const existingGroup = componentMap.get(entry.sampleMeta.componentId) ?? {
        componentId: entry.sampleMeta.componentId,
        title: entry.sampleMeta.title,
        description: entry.sampleMeta.description,
        category: entry.sampleMeta.category,
        pluginSamples: [],
        featureSamples: [],
      };

      if (entry.sampleMeta.kind === 'base') {
        existingGroup.baseSample = entry;
        existingGroup.title = entry.sampleMeta.title;
        existingGroup.description = entry.sampleMeta.description;
        existingGroup.category = entry.sampleMeta.category;
      } else if (entry.sampleMeta.kind === 'feature') {
        existingGroup.featureSamples.push(entry);
      } else {
        existingGroup.pluginSamples.push(entry);
      }

      componentMap.set(entry.sampleMeta.componentId, existingGroup);
    });

    return Array.from(componentMap.values());
  }, [excludeComponentIds, includeComponentIds, sampleEntries]);

  if (groupedComponents.length === 0) {
    return <Empty description="표시할 컴포넌트 샘플이 없습니다." />;
  }

  return (
    <div className="component-samples-layout">
      <aside className="component-samples-layout__sidebar">
        <Card title="Components" className="component-samples-layout__nav-card">
          <Anchor
            affix={false}
            items={groupedComponents.map((componentGroup) => ({
              key: componentGroup.componentId,
              href: `#component-sample-${componentGroup.componentId}`,
              title: componentGroup.title,
            }))}
          />
        </Card>
      </aside>

      <div className="component-samples-layout__content">
        <Flex vertical gap={20} className="component-samples-layout__stack">
          {groupedComponents.map((componentGroup) => (
            <Card
              key={componentGroup.componentId}
              id={`component-sample-${componentGroup.componentId}`}
              data-focus-id={`component:${componentGroup.componentId}`}
              title={componentGroup.title}
              extra={<Tag color="blue">{componentGroup.category}</Tag>}
              className="component-samples-layout__card"
            >
              <Space direction="vertical" size={16} className="component-samples-layout__section">
                <div>
                  <Paragraph>{componentGroup.description}</Paragraph>
                  <Text type="secondary" code>
                    {componentGroup.componentId}
                  </Text>
                </div>

                {componentGroup.baseSample ? (
                  <div className="component-samples-layout__sample-block">
                    <Title level={5}>Base Sample</Title>
                    <div>{createElement(componentGroup.baseSample.Sample)}</div>
                  </div>
                ) : null}

                {componentGroup.pluginSamples.length > 0 ? (
                  <div className="component-samples-layout__sample-block">
                    <Title level={5}>Plugin Samples</Title>
                    <Flex vertical gap={16}>
                      {componentGroup.pluginSamples.map(({ modulePath, Sample, sampleMeta }) => (
                        <Card
                          key={modulePath}
                          size="small"
                          data-focus-id={`component:${componentGroup.componentId}:${sampleMeta.id}`}
                          title={sampleMeta.title}
                          extra={<Text code>{sampleMeta.variantLabel ?? sampleMeta.id}</Text>}
                        >
                          <Paragraph>{sampleMeta.description}</Paragraph>
                          {createElement(Sample)}
                        </Card>
                      ))}
                    </Flex>
                  </div>
                ) : null}

                {componentGroup.featureSamples.length > 0 ? (
                  <div className="component-samples-layout__sample-block">
                    <Title level={5}>Feature Samples</Title>
                    <Flex vertical gap={16}>
                      {componentGroup.featureSamples.map(({ modulePath, Sample, sampleMeta }) => (
                        <Card
                          key={modulePath}
                          size="small"
                          data-focus-id={`component:${componentGroup.componentId}:${sampleMeta.id}`}
                          title={sampleMeta.title}
                          extra={<Text code>{sampleMeta.variantLabel ?? sampleMeta.id}</Text>}
                        >
                          <Paragraph>{sampleMeta.description}</Paragraph>
                          {createElement(Sample)}
                        </Card>
                      ))}
                    </Flex>
                  </div>
                ) : null}
              </Space>
            </Card>
          ))}
        </Flex>
      </div>
    </div>
  );
}
