"use client";

import React, { useEffect, useState, useCallback } from "react";
import { Container, Row, Col, Card, Form, FloatingLabel, Badge, Button, Stack, Spinner, ListGroup } from "react-bootstrap";
import { useForm, Controller } from "react-hook-form";
import { useToast } from "@/context/ToastContext";
import { unixToDateTime } from "@/lib/function";
import LoadingCMS from "@/components/LoadingCMS";
import HtmlEditor from "@/components/HtmlEditor";
import { useRecaptcha } from "@/hooks/useRecaptcha";

type ContactReply = {
  scr_id: number;
  scr_sc_id: number;
  scr_subject: string;
  scr_message: string;
  scr_date: number;
};

type ContactData = {
  sc_id: number;
  sc_fname: string;
  sc_lname: string;
  sc_email: string;
  sc_mobile: string;
  sc_company: string;
  sc_message: string;
  sc_date: number;
  reply_count:number;
  replies: ContactReply[];
};

type MailFormData = {
  sc_id: number;
  subject: string;
  content: string;
};

export default function Contacts() {
  const { showToast } = useToast();
  const { getToken } = useRecaptcha();

  const [contacts, setContacts] = useState<ContactData[]>([]);
  const [isLoading, setLoading] = useState(true);
  const [searchContact, setContactSearch] = useState("");
  const [selectedContact, setSelectedContact] = useState<ContactData | null>(null);
  const [fromDate, setFromDate] = useState("");
  const [toDate, setToDate] = useState("");

  const { register, handleSubmit, reset, control, formState: { errors, isSubmitting } } = useForm<MailFormData>({    
    defaultValues: {
      sc_id: 0,
      subject: "",
      content: "",
    }
  });

  const fetchContacts = useCallback(async () => {
    try {
      const res = await fetch("/api/contact/list", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
      });
      const json = await res.json();
      if (res.ok && Array.isArray(json.contactsData)) {
        setContacts(json.contactsData);
      }
    } catch {
      showToast("Contact List: Getting failed..", "danger");
    } finally {
      setLoading(false);
    }
  }, [showToast]);

  useEffect(() => {
    fetchContacts();
  }, [fetchContacts]);

  useEffect(() => {
    if (selectedContact) {
      reset();
    }
  }, [selectedContact, reset]);

  const filteredContacts = contacts.filter((contact) => {
    const matchesSearch =
      contact.sc_fname?.toLowerCase().includes(searchContact.toLowerCase()) || 
      contact.sc_lname?.toLowerCase().includes(searchContact.toLowerCase()) || 
      contact.sc_company?.toLowerCase().includes(searchContact.toLowerCase()) || 
      contact.sc_message?.toLowerCase().includes(searchContact.toLowerCase()) || 
      contact.sc_email?.toLowerCase().includes(searchContact.toLowerCase()) || 
      contact.sc_mobile?.toLowerCase().includes(searchContact.toLowerCase());
    return matchesSearch;
  });

  const onSubmit = async (data: MailFormData) => {
    try {
      const recaptchaToken = await getToken("reply_save_form");
      const res = await fetch("/api/contact/reply", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({...data,recaptchaToken}),
      });
      const result = await res.json();
      if (res.ok) {
        showToast(result.message, "success");
        reset({
          sc_id: 0,
          subject: "",
          content: "",
        });
        setSelectedContact(null);
        fetchContacts();
      }
      else {
        showToast(result.error, "danger");
      }
    } catch {
      showToast("Sending Reply failed.", "danger");
    }
  };

  const downloadExcel = async (filtered = false) => {
    try {
      const res = await fetch("/api/contact/export", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ fromDate, toDate }),
      });

      if (!res.ok) throw new Error("Download failed");

      const blob = await res.blob();
      const url = window.URL.createObjectURL(blob);

      const a = document.createElement("a");
      a.href = url;
      a.download = filtered
        ? `contacts_${fromDate}_to_${toDate}.xlsx`
        : "contacts_all.xlsx";

      a.click();
      window.URL.revokeObjectURL(url);
    } catch {
      showToast("Excel download failed", "danger");
    }
  };


  if (isLoading) return <LoadingCMS />;

  return (
    <Container fluid className="py-3">
      <Row>        
        <Col md={8}>
          <Row xs={1} md={2} className="g-3">
            <Col md={3} className="align-self-center">
              <h1 className="fs-3">Contacts <small className="text-body-secondary">({filteredContacts.length})</small></h1>
            </Col>
            <Col md={9}>              
              <Row className="g-3 mb-3">
                <Col md={4}>
                  <FloatingLabel label="Search by keyword..">
                    <Form.Control value={searchContact} onChange={(e) => setContactSearch(e.target.value)} />
                  </FloatingLabel>
                </Col>
                <Col md={3}>
                  <FloatingLabel label="From Date">
                    <Form.Control
                      type="date"
                      value={fromDate}
                      onChange={(e) => setFromDate(e.target.value)}
                    />
                  </FloatingLabel>
                </Col>
                <Col md={3}>
                  <FloatingLabel label="To Date">
                    <Form.Control
                      type="date"
                      value={toDate}
                      onChange={(e) => setToDate(e.target.value)}
                    />
                  </FloatingLabel>
                </Col>
                <Col md={2} className="d-grid">
                  <Button
                    variant="outline-success"
                    className="rounded-pill"
                    onClick={() => downloadExcel()}
                  >
                    Download
                  </Button>
                </Col>                
              </Row>
            </Col>
            {filteredContacts.map((contact, index) => (
              <Col key={index}>
                <Card className={`h-100 rounded-4 overflow-hidden ${selectedContact && selectedContact.sc_id === contact.sc_id ? 'text-bg-success' : null}`}>
                  <Card.Body>
                    <Card.Title>{contact.sc_fname} {contact.sc_lname}</Card.Title>
                    <Card.Text>{contact.sc_message}</Card.Text>
                  </Card.Body>
                  <ListGroup variant="flush">
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Company <span className="ms-3">{contact.sc_company}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Email <span className="ms-3">{contact.sc_email}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Mobile <span className="ms-3">{contact.sc_mobile}</span>
                    </ListGroup.Item>
                    <ListGroup.Item className="d-flex align-items-center justify-content-between">
                      Date <span className="ms-3">{unixToDateTime(contact.sc_date,'date')}</span>
                    </ListGroup.Item>
                  </ListGroup>
                  <Card.Footer className="d-flex align-items-center justify-content-between">
                    {contact.reply_count > 0 ? <Badge bg="primary">{contact.reply_count} Reply Exist</Badge> : <Badge bg="secondary">No Reply</Badge>}
                    <Button variant="outline-danger" className="rounded-pill" onClick={() => { setSelectedContact(contact); reset({sc_id: contact.sc_id, subject: "",content: "",});}}>
                      Send Reply
                    </Button>
                  </Card.Footer>
                </Card>
              </Col>
            ))}
          </Row>
        </Col>
        <Col md={4} className="position-sticky vh-100 overflow-y-auto" style={{ top: "1rem" }}>
          <Card className="rounded-4 bg-light">
            <Card.Body>
              <h2 className="fs-3 mb-4">Create New Reply</h2>
              <Form noValidate onSubmit={handleSubmit(onSubmit)}>
                <Row className="g-3">
                  <Col md={12}>
                    <FloatingLabel label="Mail Subject">
                      <Form.Control type="text"
                        {...register("subject", {
                          required: "Subject is required",
                          minLength: {value: 3,message: "Subject must be at least 3 characters"},
                          maxLength: {value: 150,message: "Subject cannot exceed 150 characters"},
                          validate: (value) => {
                            const cleaned = value.trim();
                            if (!cleaned) {return "Subject is required";}
                            if (!/[A-Za-z0-9]/.test(cleaned)) {return "Subject must contain letters or numbers";}
                            return true;
                          },
                        })} isInvalid={!!errors.subject} />
                      <Form.Control.Feedback type="invalid">
                        {errors.subject?.message}
                      </Form.Control.Feedback>
                    </FloatingLabel>
                  </Col>
                  <Col md={12}>
                    <Controller name="content" control={control} 
                      rules={{
                        validate: (value) => {
                          const cleaned = (value || "").trim();
                          const div = document.createElement("div");
                          div.innerHTML = cleaned;
                          const text = div.textContent?.trim() || "";
                          if (!text) { return "Content is required"; }
                          return true;
                        },
                      }} 
                      render={({ field }) => (
                        <HtmlEditor value={field.value || ""} onChange={field.onChange} />
                      )}
                    />
                    {errors.content && (<div className="invalid-feedback d-block">{errors.content.message}</div>)}                    
                  </Col>
                  {selectedContact && 
                  <Col md={12}>
                    <Stack direction="horizontal" gap={3}>
                      <Button type="submit" variant="danger" className="w-100 rounded-pill" disabled={isSubmitting}>
                        {isSubmitting ? (
                          <Stack gap={2} direction="horizontal">
                            <Spinner animation="grow" size="sm" variant="danger" />
                            <Spinner animation="grow" size="sm" variant="primary" />
                            <Spinner animation="grow" size="sm" variant="success" />
                            <span>Sending...</span>
                          </Stack>
                        ) : "Send"}
                      </Button>
                      <Button variant="outline-secondary" className="w-100 rounded-pill" onClick={() => { reset(); setSelectedContact(null); }} >
                        Cancel
                      </Button>
                    </Stack>
                    {selectedContact.reply_count > 0 ? (
                      <React.Fragment>
                        <h4 className="my-3">Existing Replies</h4>
                        {selectedContact.replies.map((reply, index) => (
                          <Card className="rounded-4 overflow-hidden mb-3" key={index}>
                            <Card.Body>
                              <Card.Title>{reply.scr_subject}</Card.Title>
                              <div dangerouslySetInnerHTML={{__html:reply.scr_message}} />
                            </Card.Body>
                            <ListGroup variant="flush">
                              <ListGroup.Item className="d-flex align-items-center justify-content-between">
                                Date <span className="ms-3">{unixToDateTime(reply.scr_date,'date')}</span>
                              </ListGroup.Item>
                            </ListGroup>
                          </Card>
                        ))}
                      </React.Fragment>
                    ) : (
                      <Card className="rounded-4 overflow-hidden my-3">
                        <Card.Body className="text-center">
                          <Card.Text>No Reply exist yet.</Card.Text>
                        </Card.Body>
                      </Card>
                    )}
                  </Col>}
                </Row>
              </Form>
            </Card.Body>
          </Card>
        </Col>
      </Row>
    </Container>
  );
}
