import React from 'react';
import GreyRowBox from '@/components/elements/GreyRowBox';
import FileIcon from './FileIcon';
import styled from 'styled-components/macro';

const cx = (...parts: Array<string | false | null | undefined>) => parts.filter(Boolean).join(' ');

const palette = {
    yellow: '#f59e0b',
    orange: '#f97316',
    blue: '#3b82f6',
    red: '#ef4444',
    purple: '#8b5cf6',
    pink: '#ec4899',
    green: '#22c55e',
    cyan: '#06b6d4',
    gray: '#6b7280',
} as const;

const hexToRgb = (hex: string) => {
    const normalized = hex.replace('#', '').trim();
    const chars = normalized.length === 3
        ? normalized.split('').map((c) => c + c).join('')
        : normalized;
    const r = parseInt(chars.slice(0, 2), 16);
    const g = parseInt(chars.slice(2, 4), 16);
    const b = parseInt(chars.slice(4, 6), 16);
    return { r, g, b };
};

const withOpacity = (hex: string, opacity: number) => {
    const { r, g, b } = hexToRgb(hex);
    return `rgba(${r}, ${g}, ${b}, ${opacity})`;
};

const darken = (hex: string, percent: number) => {
    const { r, g, b } = hexToRgb(hex);
    const adjust = (value: number) => Math.max(0, Math.min(255, Math.round(value * (1 - percent))));
    return `rgb(${adjust(r)}, ${adjust(g)}, ${adjust(b)})`;
};

const getFileTypeBaseColor = (filename: string, isFolder: boolean) => {
    if (isFolder) {
        return palette.yellow;
    }
    const ext = filename.split('.').pop()?.toLowerCase() || '';
    const lowerFilename = filename.toLowerCase();
    if (['js', 'mjs', 'cjs', 'jsx'].includes(ext)) {
        return palette.yellow;
    }
    if (['ts', 'mts', 'cts', 'tsx'].includes(ext) || ['tsconfig.json', 'jsconfig.json'].includes(lowerFilename)) {
        return palette.blue;
    }
    if (ext === 'ng' || ['component.ts', 'module.ts', 'service.ts'].some((suffix) => lowerFilename.endsWith(suffix))) {
        return palette.red;
    }
    if (['py', 'pyw', 'pyx', 'pyd', 'pyc'].includes(ext) || ['requirements.txt', 'pipfile', 'poetry.lock'].includes(lowerFilename)) {
        return palette.blue;
    }
    if (['java', 'class'].includes(ext)) {
        return palette.blue;
    }
    if (['kt', 'kts'].includes(ext)) {
        return palette.purple;
    }
    if (ext === 'scala') {
        return palette.red;
    }
    if (ext === 'groovy') {
        return palette.blue;
    }
    if (['json', 'jsonc'].includes(ext) || lowerFilename === 'package.json' || lowerFilename === 'package-lock.json') {
        return palette.yellow;
    }
    if (['yaml', 'yml'].includes(ext)) {
        return palette.red;
    }
    if (ext === 'toml' || lowerFilename === 'cargo.toml' || lowerFilename === 'cargo.lock') {
        return palette.red;
    }
    if (ext === 'xml') {
        return palette.red;
    }
    if (['html', 'htm'].includes(ext)) {
        return palette.red;
    }
    if (['css', 'scss', 'sass', 'less'].includes(ext)) {
        return palette.blue;
    }
    if (['swift'].includes(ext)) {
        return palette.orange;
    }
    if (['php', 'phtml', 'php3', 'php4', 'php5'].includes(ext) || ['composer.json', 'composer.lock'].includes(lowerFilename)) {
        return palette.purple;
    }
    if (['rb', 'erb'].includes(ext) || ['gemfile', 'gemfile.lock'].includes(lowerFilename)) {
        return palette.red;
    }
    if (ext === 'go' || lowerFilename === 'go.mod' || lowerFilename === 'go.sum') {
        return palette.cyan;
    }
    if (ext === 'rs') {
        return palette.red;
    }
    if (['c', 'h', 'cpp', 'cc', 'cxx', 'hpp', 'hxx', 'h++'].includes(ext)) {
        return palette.blue;
    }
    if (['cs', 'csx'].includes(ext)) {
        return palette.green;
    }
    if (['dart'].includes(ext)) {
        return palette.cyan;
    }
    if (['ex', 'exs'].includes(ext)) {
        return palette.purple;
    }
    if (['md', 'markdown', 'mdown', 'mkd', 'mdx'].includes(ext) || lowerFilename === 'readme.md' || lowerFilename === 'readme') {
        return palette.blue;
    }
    if (['tex', 'latex'].includes(ext)) {
        return palette.cyan;
    }
    if (['adoc', 'asciidoc'].includes(ext)) {
        return palette.red;
    }
    if (ext === 'rst') {
        return palette.gray;
    }
    if (ext === 'vue') {
        return palette.green;
    }
    if (ext === 'svelte') {
        return palette.red;
    }
    if (['sh', 'bash', 'zsh', 'fish'].includes(ext)) {
        return palette.green;
    }
    if (['bat', 'cmd'].includes(ext)) {
        return palette.blue;
    }
    if (ext === 'ps1') {
        return palette.blue;
    }
    if (['dockerfile', '.dockerignore'].includes(lowerFilename) || ext === 'dockerfile' || lowerFilename === 'docker-compose.yml' || lowerFilename === 'docker-compose.yaml') {
        return palette.blue;
    }
    if (['tf', 'tfvars'].includes(ext)) {
        return palette.purple;
    }
    if (lowerFilename.includes('kubernetes') || ext === 'k8s') {
        return palette.blue;
    }
    if (['.gitignore', '.gitattributes', '.gitmodules'].includes(lowerFilename)) {
        return palette.red;
    }
    if (lowerFilename === '.gitlab-ci.yml') {
        return palette.red;
    }
    if (['zip', 'rar', '7z', 'tar', 'gz', 'bz2', 'xz', 'tgz', 'tbz2'].includes(ext) || filename.includes('.tar.') || ext === 'jar') {
        return palette.purple;
    }
    if (['png', 'jpg', 'jpeg', 'gif', 'webp', 'bmp', 'ico', 'tiff', 'tif'].includes(ext)) {
        return palette.pink;
    }
    if (ext === 'svg') {
        return palette.yellow;
    }
    if (['mp4', 'webm', 'ogv', 'avi', 'mov', 'mkv', 'flv', 'wmv', 'm4v'].includes(ext)) {
        return palette.pink;
    }
    if (['mp3', 'wav', 'ogg', 'flac', 'm4a', 'aac', 'wma', 'aiff'].includes(ext)) {
        return palette.purple;
    }
    if (['midi', 'mid'].includes(ext)) {
        return palette.purple;
    }
    if (ext === 'pdf') {
        return palette.red;
    }
    if (ext === 'sql') {
        return palette.orange;
    }
    if (['db', 'sqlite', 'sqlite3'].includes(ext)) {
        return palette.orange;
    }
    if (['xls', 'xlsx', 'csv'].includes(ext)) {
        return palette.green;
    }
    if (['doc', 'docx'].includes(ext)) {
        return palette.blue;
    }
    if (['ppt', 'pptx'].includes(ext)) {
        return palette.red;
    }
    if (['pem', 'key', 'pub', 'crt', 'cer', 'p12', 'pfx'].includes(ext)) {
        return palette.yellow;
    }
    if (ext === 'lock') {
        return palette.gray;
    }
    if (['properties', 'conf', 'cfg', 'ini', 'config'].includes(ext) || ['.env', '.env.local', '.env.development', '.env.production'].includes(lowerFilename)) {
        return palette.yellow;
    }
    if (lowerFilename === '.editorconfig' || ext === 'editorconfig') {
        return palette.gray;
    }
    if (['yarn.lock', '.yarnrc'].includes(lowerFilename)) {
        return palette.cyan;
    }
    if (['webpack.config.js', 'webpack.config.ts'].includes(lowerFilename)) {
        return palette.blue;
    }
    if (['vite.config.js', 'vite.config.ts'].includes(lowerFilename)) {
        return palette.blue;
    }
    if (['rollup.config.js', 'rollup.config.ts'].includes(lowerFilename)) {
        return palette.red;
    }
    if (['.babelrc', 'babel.config.js', 'babel.config.json'].includes(lowerFilename)) {
        return palette.yellow;
    }
    if (['jest.config.js', 'jest.config.ts'].includes(lowerFilename)) {
        return palette.red;
    }
    if (['cypress.config.js', 'cypress.config.ts'].includes(lowerFilename)) {
        return palette.gray;
    }
    if (['vitest.config.js', 'vitest.config.ts'].includes(lowerFilename)) {
        return palette.green;
    }
    if (['test.js', 'test.ts', 'spec.js', 'spec.ts'].some((suffix) => lowerFilename.endsWith(suffix))) {
        return palette.red;
    }
    if (['.eslintrc', '.eslintrc.js', '.eslintrc.json', 'eslint.config.js'].includes(lowerFilename)) {
        return palette.purple;
    }
    if (['.prettierrc', '.prettierrc.js', '.prettierrc.json', 'prettier.config.js'].includes(lowerFilename)) {
        return palette.yellow;
    }
    if (ext === 'prisma') {
        return palette.gray;
    }
    if (ext === 'graphql' || ext === 'gql') {
        return palette.pink;
    }
    if (['license', 'licence', 'copying'].includes(lowerFilename)) {
        return palette.green;
    }
    if (['log', 'txt'].includes(ext)) {
        return palette.gray;
    }
    return palette.gray;
};

const BadgeBox = styled(GreyRowBox)`
    padding: 0.125rem;
    border: 1px solid transparent;
    width: 1.125rem;
    height: 1.125rem;
    min-width: 1.125rem;
    flex: 0 0 auto;
    align-items: center;
    justify-content: center;
    transition: background-color 150ms ease, border-color 150ms ease;
    && {
        background-color: var(--badge-bg, transparent) !important;
        border-color: var(--badge-border, transparent) !important;
    }
    &&:hover {
        background-color: var(--badge-hover-bg, var(--badge-bg, transparent)) !important;
        border-color: var(--badge-hover-border, var(--badge-border, transparent)) !important;
    }
`;

interface FileTypeBadgeProps {
    filename: string;
    isFolder: boolean;
    isOpen?: boolean;
    isActive?: boolean;
    className?: string;
}

const FileTypeBadge: React.FC<FileTypeBadgeProps> = ({ filename, isFolder, isOpen, isActive = false, className }) => {
    const base = getFileTypeBaseColor(filename, isFolder);
    const hoverBg = withOpacity(base, 0.3);
    const hoverBorder = darken(base, 0.2);
    const activeBg = withOpacity(base, 0.35);
    const activeBorder = darken(base, 0.25);

    return (
        <BadgeBox
            className={cx('shrink-0', className)}
            $hoverable={false}
            style={{
                padding: 2,
                '--badge-bg': isActive ? activeBg : 'transparent',
                '--badge-border': isActive ? activeBorder : 'transparent',
                '--badge-hover-bg': hoverBg,
                '--badge-hover-border': hoverBorder,
            } as React.CSSProperties}
        >
            <FileIcon filename={filename} isFolder={isFolder} isOpen={isOpen} />
        </BadgeBox>
    );
};

export default FileTypeBadge;
