import React, { useState } from 'react';
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogDescription,
  DialogFooter,
} from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { useToast } from "@/hooks/use-toast";
import { supabase } from '@/integrations/supabase/client';
import { Upload, FileSpreadsheet, AlertCircle, Loader2, CheckCircle2 } from 'lucide-react';
import Papa from 'papaparse';
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert";

const normalizeText = (value) => String(value ?? '').trim().replace(/\s+/g, ' ').toLowerCase();

const normalizePhone = (value) => String(value ?? '').replace(/\D/g, '');

const splitOwnerName = (value) => {
  const parts = String(value ?? '').trim().replace(/\s+/g, ' ').split(' ').filter(Boolean);

  return {
    firstName: parts[0] || 'Unknown',
    lastName: parts.slice(1).join(' ') || '',
  };
};

const getImportRowSignature = (row) => [
  normalizeText(row.unit_id),
  normalizeText(row.account_number),
  normalizeText(row.owner_name),
  normalizePhone(row.phone_number),
].join('::');

const getOwnerNameKey = (owner) => normalizeText(`${owner.first_name || ''} ${owner.last_name || ''}`);

export default function IndividualOwnerUploadDialog({ open, onOpenChange, associationId, onSuccess }) {
  const { toast } = useToast();
  const [loading, setLoading] = useState(false);
  const [parsedData, setParsedData] = useState([]);
  const [previewData, setPreviewData] = useState([]);
  const [error, setError] = useState(null);
  const [step, setStep] = useState('upload');

  const handleFileUpload = (e) => {
    const file = e.target.files[0];
    if (!file) return;

    setError(null);
    Papa.parse(file, {
      header: true,
      skipEmptyLines: true,
      complete: (results) => {
        if (results.errors.length > 0) {
          setError(`CSV Parsing Error: ${results.errors[0].message}`);
          return;
        }

        const data = results.data;
        const requiredColumns = ['account_number', 'unit_id', 'owner_name', 'phone_number'];
        const headers = results.meta.fields;
        
        const missingColumns = requiredColumns.filter(col => !headers.includes(col));
        if (missingColumns.length > 0) {
          setError(`Missing required columns: ${missingColumns.join(', ')}`);
          return;
        }

        const validRows = data
          .filter(row => row.owner_name && (row.unit_id || row.account_number))
          .map(row => ({
            account_number: row.account_number?.trim(),
            unit_id: row.unit_id?.trim(),
            owner_name: row.owner_name?.trim(),
            phone_number: row.phone_number?.trim()
          }));

        const dedupedRows = Array.from(
          new Map(validRows.map(row => [getImportRowSignature(row), row])).values()
        );
        
        if (dedupedRows.length === 0) {
          setError("No valid data found. Ensure rows have at least owner_name and either unit_id or account_number.");
          return;
        }

        setParsedData(dedupedRows);
        setPreviewData(dedupedRows.slice(0, 5));
        setStep('preview');
      },
      error: (err) => {
        setError(`File Read Error: ${err.message}`);
      }
    });
  };

  const handleSubmit = async () => {
    setLoading(true);
    setError(null);
    try {
      const timestamp = new Date().toISOString();
      const archiveDate = timestamp.slice(0, 10);

      const { data: units } = await supabase
        .from('units')
        .select('id, unit_number, account_number')
        .eq('association_id', associationId);
      
      const unitMap = new Map();
      (units || []).forEach(u => {
        const unitNumberKey = normalizeText(u.unit_number);
        const unitAccountKey = normalizeText(u.account_number);

        if (unitNumberKey) unitMap.set(unitNumberKey, u.id);
        if (unitAccountKey) unitMap.set(unitAccountKey, u.id);
        unitMap.set(u.id, u.id);
      });

      const { data: existingOwners } = await supabase
        .from('owners')
        .select('id, account_number, first_name, last_name, phone, unit_id')
        .eq('association_id', associationId)
        .eq('status', 'active');

      const existingByUnit = new Map();
      const existingByAccountNumber = new Map();

      (existingOwners || []).forEach(owner => {
        const unitKey = owner.unit_id || '__no_unit__';
        if (!existingByUnit.has(unitKey)) {
          existingByUnit.set(unitKey, []);
        }
        existingByUnit.get(unitKey).push(owner);

        const accountKey = normalizeText(owner.account_number);
        if (accountKey) {
          if (!existingByAccountNumber.has(accountKey)) {
            existingByAccountNumber.set(accountKey, []);
          }
          existingByAccountNumber.get(accountKey).push(owner);
        }
      });

      const toInsert = [];
      const toUpdate = [];
      const toArchive = [];
      const usedExistingOwnerIds = new Set();
      const importedUnitIds = new Set();
      const unresolvedRows = [];

      parsedData.forEach(row => {
        const rawUnit = row.unit_id ? String(row.unit_id).trim() : null;
        const unitKey = rawUnit ? normalizeText(rawUnit) : null;
        const accountKey = normalizeText(row.account_number);
        const resolvedUnitId =
          (unitKey && unitMap.get(unitKey)) ||
          (accountKey && unitMap.get(accountKey)) ||
          null;

        if (rawUnit && !resolvedUnitId) {
          unresolvedRows.push(rawUnit);
        }

        if (resolvedUnitId) {
          importedUnitIds.add(resolvedUnitId);
        }

        const { firstName, lastName } = splitOwnerName(row.owner_name);

        const ownerData = {
          association_id: associationId,
          account_number: row.account_number || null,
          first_name: firstName,
          last_name: lastName,
          phone: row.phone_number || null,
          unit_id: resolvedUnitId,
          move_out_date: null,
          status: 'active',
        };

        const existingCandidates = resolvedUnitId ? (existingByUnit.get(resolvedUnitId) || []) : [];
        const normalizedName = normalizeText(row.owner_name);
        const normalizedPhone = normalizePhone(row.phone_number);

        let matchedOwner = existingCandidates.find(owner =>
          !usedExistingOwnerIds.has(owner.id) &&
          getOwnerNameKey(owner) === normalizedName
        ) || null;

        if (!matchedOwner && accountKey) {
          const accountMatches = (existingByAccountNumber.get(accountKey) || []).filter(owner =>
            !usedExistingOwnerIds.has(owner.id) &&
            (!resolvedUnitId || owner.unit_id === resolvedUnitId)
          );

          if (accountMatches.length === 1) {
            matchedOwner = accountMatches[0];
          }
        }

        if (!matchedOwner && normalizedPhone) {
          const phoneMatches = existingCandidates.filter(owner =>
            !usedExistingOwnerIds.has(owner.id) &&
            normalizePhone(owner.phone) === normalizedPhone
          );

          if (phoneMatches.length === 1) {
            matchedOwner = phoneMatches[0];
          }
        }

        if (matchedOwner) {
          usedExistingOwnerIds.add(matchedOwner.id);
          toUpdate.push({ id: matchedOwner.id, ...ownerData, updated_at: timestamp });
        } else {
          toInsert.push(ownerData);
        }
      });

      importedUnitIds.forEach(unitId => {
        const ownersForUnit = existingByUnit.get(unitId) || [];
        ownersForUnit.forEach(owner => {
          if (!usedExistingOwnerIds.has(owner.id)) {
            toArchive.push(owner.id);
          }
        });
      });

      if (toInsert.length > 0) {
        const chunkSize = 100;
        for (let i = 0; i < toInsert.length; i += chunkSize) {
          const chunk = toInsert.slice(i, i + chunkSize);
          const { error: insertError } = await supabase.from('owners').insert(chunk);
          if (insertError) throw insertError;
        }
      }

      for (const owner of toUpdate) {
        const { id, ...updates } = owner;
        const { error: updateError } = await supabase
          .from('owners')
          .update(updates)
          .eq('id', id);
        if (updateError) throw updateError;
      }

      if (toArchive.length > 0) {
        const chunkSize = 100;
        for (let i = 0; i < toArchive.length; i += chunkSize) {
          const chunk = toArchive.slice(i, i + chunkSize);
          const { error: archiveError } = await supabase
            .from('owners')
            .update({
              status: 'archived',
              move_out_date: archiveDate,
              updated_at: timestamp,
            })
            .in('id', chunk);

          if (archiveError) throw archiveError;
        }
      }

      unresolvedRows.forEach(unitReference => {
        console.warn(`Could not resolve unit during import: "${unitReference}"`);
      });

      setStep('success');
      const msg = [];
      if (toInsert.length > 0) msg.push(`${toInsert.length} new`);
      if (toUpdate.length > 0) msg.push(`${toUpdate.length} updated`);
      if (toArchive.length > 0) msg.push(`${toArchive.length} archived`);
      toast({
        title: "Upload Successful",
        description: `Successfully imported owners: ${msg.join(', ')}.`
      });
      if (onSuccess) onSuccess();
    } catch (err) {
      console.error("Upload error:", err);
      if (err.code === '23505') {
        setError("Duplicate records detected. Some account numbers or IDs already exist in the database.");
      } else {
        setError(`Upload Failed: ${err.message}`);
      }
      toast({
        variant: "destructive",
        title: "Error",
        description: "Failed to upload owners."
      });
    } finally {
      setLoading(false);
    }
  };

  const handleClose = () => {
    setParsedData([]);
    setPreviewData([]);
    setError(null);
    setStep('upload');
    onOpenChange(false);
  };

  return (
    <Dialog open={open} onOpenChange={handleClose}>
      <DialogContent className="sm:max-w-[600px]">
        <DialogHeader>
          <DialogTitle>Upload Individual Owners</DialogTitle>
          <DialogDescription>
            Import owner details via CSV. Required columns: account_number, unit_id, owner_name, phone_number.
          </DialogDescription>
        </DialogHeader>

        {step === 'upload' && (
          <div className="py-8 text-center space-y-4">
            <div className="flex justify-center">
              <div className="h-24 w-24 rounded-full bg-muted flex items-center justify-center border-2 border-dashed border-border">
                <FileSpreadsheet className="h-10 w-10 text-muted-foreground" />
              </div>
            </div>
            
            <div className="max-w-xs mx-auto">
              <label htmlFor="file-upload" className="cursor-pointer">
                <div className="flex items-center justify-center w-full px-4 py-2 bg-primary text-primary-foreground rounded-md hover:bg-primary/90 transition-colors gap-2 font-medium">
                  <Upload className="h-4 w-4" />
                  Select CSV File
                </div>
                <input 
                  id="file-upload" 
                  type="file" 
                  accept=".csv" 
                  className="hidden" 
                  onChange={handleFileUpload}
                />
              </label>
              <p className="text-xs text-muted-foreground mt-2">
                Supported format: .csv
              </p>
            </div>

            {error && (
              <Alert variant="destructive" className="mt-4 text-left">
                <AlertCircle className="h-4 w-4" />
                <AlertTitle>Error</AlertTitle>
                <AlertDescription>{error}</AlertDescription>
              </Alert>
            )}
          </div>
        )}

        {step === 'preview' && (
          <div className="space-y-4">
            <div className="flex items-center justify-between">
              <h3 className="text-sm font-medium">Preview ({parsedData.length} records found)</h3>
            </div>
            
            <div className="border rounded-md">
              <Table>
                <TableHeader>
                  <TableRow>
                    <TableHead>Account</TableHead>
                    <TableHead>Unit</TableHead>
                    <TableHead>Name</TableHead>
                    <TableHead>Phone</TableHead>
                  </TableRow>
                </TableHeader>
                <TableBody>
                  {previewData.map((row, i) => (
                    <TableRow key={i}>
                      <TableCell>{row.account_number}</TableCell>
                      <TableCell>{row.unit_id}</TableCell>
                      <TableCell>{row.owner_name}</TableCell>
                      <TableCell>{row.phone_number}</TableCell>
                    </TableRow>
                  ))}
                  {parsedData.length > 5 && (
                    <TableRow>
                      <TableCell colSpan={4} className="text-center text-xs text-muted-foreground italic">
                        ...and {parsedData.length - 5} more rows
                      </TableCell>
                    </TableRow>
                  )}
                </TableBody>
              </Table>
            </div>

            {error && (
              <Alert variant="destructive">
                <AlertCircle className="h-4 w-4" />
                <AlertTitle>Error</AlertTitle>
                <AlertDescription>{error}</AlertDescription>
              </Alert>
            )}

            <DialogFooter className="gap-2 sm:gap-0">
              <Button variant="outline" onClick={() => setStep('upload')}>Back</Button>
              <Button onClick={handleSubmit} disabled={loading}>
                {loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
                Import {parsedData.length} Owners
              </Button>
            </DialogFooter>
          </div>
        )}

        {step === 'success' && (
          <div className="py-8 text-center space-y-4">
            <div className="flex justify-center mb-4">
              <div className="h-16 w-16 bg-emerald-100 rounded-full flex items-center justify-center">
                <CheckCircle2 className="h-8 w-8 text-emerald-600" />
              </div>
            </div>
            <h3 className="text-lg font-semibold">Import Successful!</h3>
            <p className="text-muted-foreground">
              Successfully processed {parsedData.length} individual owner records.
            </p>
            <Button onClick={handleClose} className="mt-4">Close</Button>
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
