import { useState, useRef } from 'react';
import {
  Title, Table, Group, Button, Stack, Text, Modal, TextInput,
  NumberInput, Select, Textarea, Badge, ActionIcon, Loader, Center,
  Card, SimpleGrid, Progress, Switch, Tooltip,
} from '@mantine/core';
import { DateInput } from '@mantine/dates';
import { useForm } from '@mantine/form';
import { useDisclosure } from '@mantine/hooks';
import { notifications } from '@mantine/notifications';
import { IconPlus, IconEdit, IconUpload, IconDownload, IconLock, IconLockOpen } from '@tabler/icons-react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import api from '../../services/api';
import { parseCSV, downloadBlob } from '../../utils/csv';

// ---------------------------------------------------------------------------
// Types & constants
// ---------------------------------------------------------------------------

interface Project {
  id: string;
  name: string;
  description: string;
  category: string;
  estimated_cost: string;
  actual_cost: string;
  current_fund_balance: string;
  annual_contribution: string;
  fund_source: string;
  funded_percentage: string;
  useful_life_years: number;
  remaining_life_years: number;
  condition_rating: number;
  last_replacement_date: string;
  next_replacement_date: string;
  planned_date: string;
  target_year: number;
  target_month: number;
  status: string;
  priority: number;
  account_id: string;
  notes: string;
  is_active: boolean;
  is_funding_locked: boolean;
}

const FUTURE_YEAR = 9999;

const categories = [
  'roof', 'pool', 'hvac', 'paving', 'painting',
  'fencing', 'elevator', 'irrigation', 'clubhouse', 'other',
];

const statusColors: Record<string, string> = {
  planned: 'blue',
  approved: 'green',
  in_progress: 'yellow',
  completed: 'teal',
  deferred: 'gray',
  cancelled: 'red',
};

const fundSourceColors: Record<string, string> = {
  operating: 'gray',
  reserve: 'violet',
  special_assessment: 'orange',
};

const fmt = (v: string | number) =>
  parseFloat(String(v || '0')).toLocaleString('en-US', { style: 'currency', currency: 'USD' });

// ---------------------------------------------------------------------------
// Main page component
// ---------------------------------------------------------------------------

export function ProjectsPage() {
  const [opened, { open, close }] = useDisclosure(false);
  const [editing, setEditing] = useState<Project | null>(null);
  const queryClient = useQueryClient();
  const fileInputRef = useRef<HTMLInputElement>(null);

  // ---- Data fetching ----

  const { data: projects = [], isLoading } = useQuery<Project[]>({
    queryKey: ['projects'],
    queryFn: async () => {
      const { data } = await api.get('/projects');
      return data;
    },
  });

  // ---- Derived summary values ----

  const totalEstimatedCost = projects.reduce(
    (sum, p) => sum + parseFloat(p.estimated_cost || '0'),
    0,
  );

  const reserveProjects = projects.filter((p) => p.fund_source === 'reserve');

  const totalFundedReserve = reserveProjects.reduce(
    (sum, p) => sum + parseFloat(p.current_fund_balance || '0'),
    0,
  );

  const totalReserveReplacementCost = reserveProjects.reduce(
    (sum, p) => sum + parseFloat(p.estimated_cost || '0'),
    0,
  );

  const pctFundedReserve =
    totalReserveReplacementCost > 0
      ? (totalFundedReserve / totalReserveReplacementCost) * 100
      : 0;

  // ---- Form setup ----

  const currentYear = new Date().getFullYear();

  const targetYearOptions = [
    ...Array.from({ length: 6 }, (_, i) => ({
      value: String(currentYear + i),
      label: String(currentYear + i),
    })),
    { value: String(FUTURE_YEAR), label: 'Future (Beyond 5-Year)' },
  ];

  const monthOptions = Array.from({ length: 12 }, (_, i) => ({
    value: String(i + 1),
    label: new Date(2000, i).toLocaleString('default', { month: 'long' }),
  }));

  const form = useForm({
    initialValues: {
      name: '',
      category: 'other',
      description: '',
      fund_source: 'reserve',
      status: 'planned',
      priority: 3,
      estimated_cost: 0,
      actual_cost: 0,
      current_fund_balance: 0,
      annual_contribution: 0,
      funded_percentage: 0,
      useful_life_years: 20,
      remaining_life_years: 10,
      condition_rating: 5,
      last_replacement_date: null as Date | null,
      next_replacement_date: null as Date | null,
      planned_date: null as Date | null,
      target_year: currentYear,
      target_month: 6,
      notes: '',
      is_funding_locked: false,
    },
    validate: {
      name: (v) => (v.length > 0 ? null : 'Required'),
      estimated_cost: (v) => (v > 0 ? null : 'Required'),
    },
  });

  // ---- Mutations ----

  const saveMutation = useMutation({
    mutationFn: (values: any) => {
      const payload = {
        ...values,
        last_replacement_date:
          values.last_replacement_date?.toISOString?.()?.split('T')[0] || null,
        next_replacement_date:
          values.next_replacement_date?.toISOString?.()?.split('T')[0] || null,
        planned_date:
          values.planned_date?.toISOString?.()?.split('T')[0] || null,
      };
      return editing
        ? api.put(`/projects/${editing.id}`, payload)
        : api.post('/projects', payload);
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['projects'] });
      notifications.show({
        message: editing ? 'Project updated' : 'Project created',
        color: 'green',
      });
      close();
      setEditing(null);
      form.reset();
    },
    onError: (err: any) => {
      notifications.show({
        message: err.response?.data?.message || 'Error',
        color: 'red',
      });
    },
  });

  const importMutation = useMutation({
    mutationFn: async (rows: Record<string, string>[]) => {
      const { data } = await api.post('/projects/import', rows);
      return data;
    },
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: ['projects'] });
      let msg = `Imported: ${data.created} created, ${data.updated} updated`;
      if (data.errors?.length) msg += `. ${data.errors.length} error(s): ${data.errors.slice(0, 3).join('; ')}`;
      notifications.show({ message: msg, color: data.errors?.length ? 'yellow' : 'green', autoClose: 10000 });
    },
    onError: (err: any) => { notifications.show({ message: err.response?.data?.message || 'Import failed', color: 'red' }); },
  });

  const handleExport = async () => {
    try {
      const response = await api.get('/projects/export', { responseType: 'blob' });
      downloadBlob(response.data, 'projects.csv');
    } catch { notifications.show({ message: 'Export failed', color: 'red' }); }
  };

  const handleFileChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    const file = event.target.files?.[0];
    if (!file) return;
    const reader = new FileReader();
    reader.onload = (e) => {
      const text = e.target?.result as string;
      if (!text) { notifications.show({ message: 'Could not read file', color: 'red' }); return; }
      const rows = parseCSV(text);
      if (!rows.length) { notifications.show({ message: 'No data rows found', color: 'red' }); return; }
      importMutation.mutate(rows);
    };
    reader.readAsText(file);
    event.target.value = '';
  };

  // ---- Handlers ----

  const handleEdit = (p: Project) => {
    setEditing(p);
    form.setValues({
      name: p.name,
      category: p.category || 'other',
      description: p.description || '',
      fund_source: p.fund_source || 'reserve',
      status: p.status || 'planned',
      priority: p.priority || 3,
      estimated_cost: parseFloat(p.estimated_cost || '0'),
      actual_cost: parseFloat(p.actual_cost || '0'),
      current_fund_balance: parseFloat(p.current_fund_balance || '0'),
      annual_contribution: parseFloat(p.annual_contribution || '0'),
      funded_percentage: parseFloat(p.funded_percentage || '0'),
      useful_life_years: p.useful_life_years || 0,
      remaining_life_years: p.remaining_life_years || 0,
      condition_rating: p.condition_rating || 5,
      last_replacement_date: p.last_replacement_date
        ? new Date(p.last_replacement_date)
        : null,
      next_replacement_date: p.next_replacement_date
        ? new Date(p.next_replacement_date)
        : null,
      planned_date: p.planned_date ? new Date(p.planned_date) : null,
      target_year: p.target_year || currentYear,
      target_month: p.target_month || 6,
      notes: p.notes || '',
      is_funding_locked: p.is_funding_locked || false,
    });
    open();
  };

  const handleNew = () => {
    setEditing(null);
    form.reset();
    open();
  };

  // ---- Helpers for table rendering ----

  const formatDate = (dateStr: string | null | undefined) => {
    if (!dateStr) return '-';
    const d = new Date(dateStr);
    if (isNaN(d.getTime())) return '-';
    return d.toLocaleDateString('en-US', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
    });
  };

  const conditionBadge = (rating: number | null | undefined) => {
    if (rating == null) return <Text c="dimmed">-</Text>;
    const color = rating >= 7 ? 'green' : rating >= 4 ? 'yellow' : 'red';
    return (
      <Badge size="sm" color={color}>
        {rating}/10
      </Badge>
    );
  };

  const fundedPercentageCell = (project: Project) => {
    if (project.fund_source !== 'reserve') {
      return <Text c="dimmed">-</Text>;
    }
    const cost = parseFloat(project.estimated_cost || '0');
    const funded = parseFloat(project.current_fund_balance || '0');
    const pct = cost > 0 ? (funded / cost) * 100 : 0;
    const color = pct >= 70 ? 'green' : pct >= 40 ? 'yellow' : 'red';
    return (
      <Group gap={4} justify="flex-end">
        {project.is_funding_locked && (
          <Tooltip label="Funding manually locked">
            <IconLock size={14} style={{ color: 'var(--mantine-color-blue-5)' }} />
          </Tooltip>
        )}
        <Text span c={color} ff="monospace">
          {pct.toFixed(0)}%
        </Text>
      </Group>
    );
  };

  // ---- Loading state ----

  if (isLoading) return <Center h={300}><Loader /></Center>;

  // ---- Render ----

  return (
    <Stack>
      {/* Header */}
      <Group justify="space-between">
        <Title order={2}>Projects</Title>
        <Group>
          <Button variant="light" leftSection={<IconDownload size={16} />} onClick={handleExport} disabled={projects.length === 0}>
            Export CSV
          </Button>
          <Button variant="light" leftSection={<IconUpload size={16} />} onClick={() => fileInputRef.current?.click()}
            loading={importMutation.isPending}>
            Import CSV
          </Button>
          <input type="file" ref={fileInputRef} accept=".csv,.txt" style={{ display: 'none' }} onChange={handleFileChange} />
          <Button leftSection={<IconPlus size={16} />} onClick={handleNew}>
            + Add Project
          </Button>
        </Group>
      </Group>

      {/* Summary Cards */}
      <SimpleGrid cols={{ base: 1, sm: 3 }}>
        <Card withBorder p="md">
          <Text size="xs" c="dimmed" tt="uppercase" fw={700}>
            Total Estimated Cost
          </Text>
          <Text fw={700} size="xl">
            {fmt(totalEstimatedCost)}
          </Text>
        </Card>
        <Card withBorder p="md">
          <Text size="xs" c="dimmed" tt="uppercase" fw={700}>
            Total Funded - Reserve Only
          </Text>
          <Text fw={700} size="xl" c="green">
            {fmt(totalFundedReserve)}
          </Text>
        </Card>
        <Card withBorder p="md">
          <Text size="xs" c="dimmed" tt="uppercase" fw={700}>
            Percent Funded - Reserve Only
          </Text>
          <Group>
            <Text
              fw={700}
              size="xl"
              c={
                pctFundedReserve >= 70
                  ? 'green'
                  : pctFundedReserve >= 40
                    ? 'yellow'
                    : 'red'
              }
            >
              {pctFundedReserve.toFixed(1)}%
            </Text>
            <Progress
              value={pctFundedReserve}
              size="lg"
              style={{ flex: 1 }}
              color={
                pctFundedReserve >= 70
                  ? 'green'
                  : pctFundedReserve >= 40
                    ? 'yellow'
                    : 'red'
              }
            />
          </Group>
        </Card>
      </SimpleGrid>

      {/* Projects Table */}
      <Table striped highlightOnHover>
        <Table.Thead>
          <Table.Tr>
            <Table.Th>Project Name</Table.Th>
            <Table.Th>Category</Table.Th>
            <Table.Th>Fund Source</Table.Th>
            <Table.Th ta="right">Estimated Cost</Table.Th>
            <Table.Th ta="right">Funded %</Table.Th>
            <Table.Th>Condition</Table.Th>
            <Table.Th>Status</Table.Th>
            <Table.Th>Planned Date</Table.Th>
            <Table.Th></Table.Th>
          </Table.Tr>
        </Table.Thead>
        <Table.Tbody>
          {projects.map((p) => (
            <Table.Tr key={p.id}>
              <Table.Td>
                <Text fw={500}>{p.name}</Text>
                {p.description && (
                  <Text size="xs" c="dimmed" lineClamp={1}>
                    {p.description}
                  </Text>
                )}
              </Table.Td>
              <Table.Td>
                <Badge size="sm" variant="light">
                  {p.category
                    ? p.category.charAt(0).toUpperCase() + p.category.slice(1)
                    : '-'}
                </Badge>
              </Table.Td>
              <Table.Td>
                <Badge
                  size="sm"
                  variant="light"
                  color={fundSourceColors[p.fund_source] || 'gray'}
                >
                  {p.fund_source?.replace('_', ' ') || '-'}
                </Badge>
              </Table.Td>
              <Table.Td ta="right" ff="monospace">
                {fmt(p.estimated_cost)}
              </Table.Td>
              <Table.Td ta="right">{fundedPercentageCell(p)}</Table.Td>
              <Table.Td>{conditionBadge(p.condition_rating)}</Table.Td>
              <Table.Td>
                <Badge
                  size="sm"
                  color={statusColors[p.status] || 'gray'}
                >
                  {p.status?.replace('_', ' ') || '-'}
                </Badge>
              </Table.Td>
              <Table.Td>{formatDate(p.planned_date)}</Table.Td>
              <Table.Td>
                <ActionIcon variant="subtle" onClick={() => handleEdit(p)}>
                  <IconEdit size={16} />
                </ActionIcon>
              </Table.Td>
            </Table.Tr>
          ))}
          {projects.length === 0 && (
            <Table.Tr>
              <Table.Td colSpan={9}>
                <Text ta="center" c="dimmed" py="lg">
                  No projects yet
                </Text>
              </Table.Td>
            </Table.Tr>
          )}
        </Table.Tbody>
      </Table>

      {/* Create / Edit Modal */}
      <Modal
        opened={opened}
        onClose={close}
        title={editing ? 'Edit Project' : 'New Project'}
        size="lg"
      >
        <form onSubmit={form.onSubmit((v) => saveMutation.mutate(v))}>
          <Stack>
            {/* Row 1: Name + Category */}
            <Group grow>
              <TextInput
                label="Name"
                required
                {...form.getInputProps('name')}
              />
              <Select
                label="Category"
                data={categories.map((c) => ({
                  value: c,
                  label: c.charAt(0).toUpperCase() + c.slice(1),
                }))}
                {...form.getInputProps('category')}
              />
            </Group>

            {/* Row 2: Description */}
            <Textarea
              label="Description"
              {...form.getInputProps('description')}
            />

            {/* Row 3: Fund Source, Status, Priority */}
            <Group grow>
              <Select
                label="Fund Source"
                data={[
                  { value: 'operating', label: 'Operating' },
                  { value: 'reserve', label: 'Reserve' },
                  { value: 'special_assessment', label: 'Special Assessment' },
                ]}
                {...form.getInputProps('fund_source')}
              />
              <Select
                label="Status"
                data={Object.keys(statusColors).map((s) => ({
                  value: s,
                  label: s.replace(/_/g, ' ').replace(/\b\w/g, (l) => l.toUpperCase()),
                }))}
                {...form.getInputProps('status')}
              />
              <NumberInput
                label="Priority (1-5)"
                min={1}
                max={5}
                {...form.getInputProps('priority')}
              />
            </Group>

            {/* Row 4: Estimated Cost, Actual Cost */}
            <Group grow>
              <NumberInput
                label="Estimated Cost"
                required
                prefix="$"
                decimalScale={2}
                min={0}
                {...form.getInputProps('estimated_cost')}
              />
              <NumberInput
                label="Actual Cost"
                prefix="$"
                decimalScale={2}
                min={0}
                {...form.getInputProps('actual_cost')}
              />
            </Group>

            {/* Row 5: Conditional reserve fields */}
            {form.values.fund_source === 'reserve' && (
              <>
                <Switch
                  label="Lock Funding"
                  description="When locked, the fund balance and percentage you set here will be used as-is instead of being auto-calculated from the reserve balance"
                  {...form.getInputProps('is_funding_locked', { type: 'checkbox' })}
                />
                <Group grow>
                  <NumberInput
                    label="Current Fund Balance"
                    prefix="$"
                    decimalScale={2}
                    min={0}
                    disabled={!form.values.is_funding_locked}
                    {...form.getInputProps('current_fund_balance')}
                  />
                  <NumberInput
                    label="Annual Contribution"
                    prefix="$"
                    decimalScale={2}
                    min={0}
                    {...form.getInputProps('annual_contribution')}
                  />
                  <NumberInput
                    label="Funded Percentage"
                    suffix="%"
                    decimalScale={1}
                    min={0}
                    max={100}
                    disabled={!form.values.is_funding_locked}
                    {...form.getInputProps('funded_percentage')}
                  />
                </Group>
                <Group grow>
                  <NumberInput
                    label="Useful Life (years)"
                    min={0}
                    {...form.getInputProps('useful_life_years')}
                  />
                  <NumberInput
                    label="Remaining Life (years)"
                    min={0}
                    decimalScale={1}
                    {...form.getInputProps('remaining_life_years')}
                  />
                  <NumberInput
                    label="Condition Rating (1-10)"
                    min={1}
                    max={10}
                    {...form.getInputProps('condition_rating')}
                  />
                </Group>
              </>
            )}

            {/* Row 6: Last / Next Replacement Date */}
            <Group grow>
              <DateInput
                label="Last Replacement Date"
                clearable
                {...form.getInputProps('last_replacement_date')}
              />
              <DateInput
                label="Next Replacement Date"
                clearable
                {...form.getInputProps('next_replacement_date')}
              />
            </Group>

            {/* Row 7: Planned Date */}
            <DateInput
              label="Planned Date"
              description="Defaults to Next Replacement Date if not set"
              clearable
              {...form.getInputProps('planned_date')}
            />

            {/* Row 8: Target Year + Target Month */}
            <Group grow>
              <Select
                label="Target Year"
                data={targetYearOptions}
                value={String(form.values.target_year)}
                onChange={(v) => form.setFieldValue('target_year', Number(v))}
              />
              <Select
                label="Target Month"
                data={monthOptions}
                value={String(form.values.target_month)}
                onChange={(v) => form.setFieldValue('target_month', Number(v))}
              />
            </Group>

            {/* Row 9: Notes */}
            <Textarea label="Notes" {...form.getInputProps('notes')} />

            <Button type="submit" loading={saveMutation.isPending}>
              {editing ? 'Update' : 'Create'}
            </Button>
          </Stack>
        </form>
      </Modal>
    </Stack>
  );
}
